Swift中的错误处理:从一个枚举到另一个枚举的错误

时间:2019-04-02 20:39:05

标签: swift error-handling

我在 ServiceClient 中有此代码。它处理服务级调用,例如signIn(user, password, completion)listObjects(completion)addObject(objectID, content, completion)getObject(id, completion)等。它包含(但不子类化) APIClient ,仅执行诸如perform(request, completion)之类的基本HTTPS服务。

我真的不希望位于此之上的控制器成功处理404,这意味着将错误捕获在ServiceClient中。因此,想法是APIClient处理网络错误,而ServiceClient处理意外的HTTP结果。

因此,我最终在ServiceClient中做到了这一点,其中invalidURL之类的错误已从APIClient枚举转换为ServiceClient枚举:

apiClient.perform(request) {result in
    switch result {
    case .success(let data):
        guard data.statusCode == 200 else {
            completion(.failure(.badResponse))
            return
        }
        completion(.success(data))
    case .failure(let error):
        switch error {
        case .invalidURL:
            completion(.failure(.invalidURL))
        case .requestFailed:
            completion(.failure(.requestFailed))
        case .decodingFailure:
            completion(.failure(.decodingFailure))
        }
    }
}

我认为在这种情况下,我将使APIClient处理无效的HTTP状态代码,但是对此,更通用的解决方案是什么?在某些时候,我需要为不同的服务客户端使用不同的错误代码,这时再次成为问题。

1 个答案:

答案 0 :(得分:2)

我建议对 ServiceClient APIClient 使用Int类型枚举。 据我了解,这是您的自定义枚举。

因此,假设您拥有ServiceClientErrorAPIClientError,则可以使用以下方式实现它们:

enum ServiceClientError: Int {
    case invalidURL, requestFailed, decodingFailure
}
enum APIClientError: Int {
    case invalidURL, requestFailed, decodingFailure
}

您可以创建自定义转换方法:

extension ServiceClientError {
    static func create(from apiClientError: APIClientError) -> ServiceClientError {
        return ServiceClientError(rawValue: apiClientError.rawValue)
    }
}

想要的功能:

apiClient.perform(request) {result in
    switch result {
    case .success(let data):
        guard data.statusCode == 200 else {
            completion(.failure(.badResponse))
            return
        }
        completion(.success(data))
    case .failure(let error):
        guard let serviceClientError = ServiceClientError.create(from: error) else {
            /// Handle incorrect behavior
            fatalError("Wrong enumeration mapping")
            return
         }
         completion(.failure(serviceClientError))
    }
}