I am using combine to handle the network response. I am stuck here to handle the common errors. Can you please help me how Can I handle the errors.
func performRequest<T:Decodable>(router:APIConfiguration, decodeType:T.Type) ->AnyPublisher<DataResponse<T, NetworkError>, Never> {
guard let url = URL.init(string: router.requestedURL) else {
return Fail(error: NetworkError.init(code: 2345, message: "Bad URL")).eraseToAnyPublisher()
}
let storage = KeycheinStorage()
print(router.requestedURL,router.parameters ?? [:])
return AF.request(router.requestedURL, method: router.method, parameters: router.parameters, interceptor: AuthTokenInterceptor(storage: storage))
.validate()
.publishDecodable(type: T.self)
.map { response in
response.mapError { error in
let networkError = response.data.flatMap {
try? JSONDecoder().decode(NetworkError.self, from: $0)
} ?? NetworkError(error)
ErrorHandler.default.handle(networkError)
return networkError
}
}
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
2
Answers
The issue is that the method you are building specifies that it never will return an error, but then you try to do exactly that. You are defining
Never
as the failure type in the return types of your method declaration:func performRequest<T:Decodable> ... -> AnyPublisher<DataResponse<T, NetworkError>, Never>
You can fix that by not using
Never
, but for exampleError
like this:func performRequest<T:Decodable> ... -> AnyPublisher<DataResponse<T, NetworkError>, Error>
Then you will be able to send any error in the publisher.
As suggested by @Joakim Danielson, you can use
Just
here, you just need to wrap yourNetworkError
in aDataResponse
. Unfortunately there’s no convenient initializer, so you need to be pretty verbose.However, instead of doing that I suggest you simply adopt Alamofire’s
URLRequestConvertible
for yourAPIConfiguration
type so Alamofire can handle the URL checking and error production for you.Additionally, Alamofire’s completion handlers and even publishers complete on the main queue by default, so the
receive(on:)
call is unnecessary.