casillas
casillas

Reputation: 16813

Emitting Error from bottom to top through call hierarchy

I have the following implementation where I am parsing the data first from School -> then ClassRoom and then -> User decoding. However, I wonder if any issues happens within the decoding or fetching procedure; how could I able to pass it all the way to ViewController. Please see //TODO marks in the following code

SchoolViewController.swift

activityIndicator.startAnimating()

schoolVM.fetchingSchoolList() { error in
  DispatchQueue.main.async {
    if error == nil {
      self.schoolCollectionView.reloadData()
    } else {
      // TODO : show an alert here
    }
    self.activityIndicator.stopAnimating()
  }
}

SchoolViewModal.swift

enum ViewModalError: Error {
  case SchoolLevelError
  case ClassroomLevelError
  case UserLevelError
}

func fetchingSchoolList(
  urlString: String = URL,
  completion: @escaping(Error?) -> ()
) {
   let operation = Operation(urlSession: URLSession(urlConfig))
   operation.dataRequest(networkRequest, successHandler: {[weak self] data in
    self?.classroomParsing(data)
    completion(nil)
   }, failureHandler: { [weak self] error in
    //TODO : SchoolLevelError
    completion(error)
    })
   } catch {
    // TODO : SchoolLevelError
     completion(error)
   }
}

private func classroomParsing(_ classroomData: Data) {
 do {
    let classroom = try decoder.decode(Classroom.self, from: classroomData)
    userParsing(classroom.userData)
  } catch {
    // TODO : error handling
    // ClassroomLevelError
 }

private func userParsing(_ userData:User) {
  do {
    let users = try decoder.decode(User.self, from: userData)
  } catch {
    // TODO : error handling
    // UserLevelError
  }
}

Upvotes: 0

Views: 34

Answers (1)

Paulw11
Paulw11

Reputation: 114975

You can simply have your parsing functions throw the relevant error. If parsing fails then pass the error to the completion handler.

func fetchingSchoolList(
  urlString: String = URL,
  completion: @escaping(Error?) -> ()
) {
   let operation = Operation(urlSession: URLSession(urlConfig))
   operation.dataRequest(networkRequest, successHandler: {[weak self] data in
    do {
        try self?.classroomParsing(data)
        completion(nil)
    }
    catch {
        completion(error)
    }

   }, failureHandler: { [weak self] error in
    //TODO : SchoolLevelError
    completion(error)
    })
   } catch {
    // TODO : SchoolLevelError
     completion(error)
   }
}

private func classroomParsing(_ classroomData: Data) throws {
 do {
    let classroom = try decoder.decode(Classroom.self, from: classroomData)
    try userParsing(classroom.userData)
  } catch {
    throw(ViewModelError.ClassroomLevelError)
 }

private func userParsing(_ userData:User) throws {
  do {
    let users = try decoder.decode(User.self, from: userData)
  } catch {
    throw(ViewModelError.UserLevelError)
  }
}

Upvotes: 1

Related Questions