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()
}
CodePudding user response:
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 example Error
like this:
func performRequest<T:Decodable> ... -> AnyPublisher<DataResponse<T, NetworkError>, Error>
Then you will be able to send any error in the publisher.
CodePudding user response:
As suggested by @Joakim Danielson, you can use Just
here, you just need to wrap your NetworkError
in a DataResponse
. Unfortunately there's no convenient initializer, so you need to be pretty verbose.
Just(DataResponse<T, NetworkError>(request: nil,
response: nil,
data: nil,
metrics: nil,
serializationDuration: 0,
result: .failure(<your error>))
However, instead of doing that I suggest you simply adopt Alamofire's URLRequestConvertible
for your APIConfiguration
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.