In my http request code, I'm switching over the (data, response, error)
tuple passed to the completion handler in dataTask(with:completionHandler:)
and turning it into a promise, like so:
func dataTask(with request: URLRequest) -> Promise<Data?, RequestError> {
return Promise { done in
let task = self.urlSession.dataTask(with: request) { data, response, error in
let status = HTTPStatus(form: response)
// Error: Switch must be exhaustive
switch (error, status, data) {
case let (urlError as URLError, _, _):
done(.failure(.networkError(urlError.code)))
case let (error as NSError, _, _):
done(.failure(.other(error)))
case let (_, _, data?) where data.containsGeoblockError():
done(.failure(.geoblocked))
case let (_, status?, data) where status.isFailure:
done(.failure(.httpError(status, data: data)))
// Warning: Case is already handled by previous patterns; consider removing it
case let (_, _, data):
done(.success(data))
}
}
task.resume()
}
}
I've been able to reduce the example to this:
let error: Error?
switch error {
case let error as NSError:
// error should be non-nil and bridged to NSError
case .none:
// error should be nil
}
The exhaustivity checker seems to think that the let error as NSError
line will catch every case. But it doesn't catch the nil-case. I can trivially fix it like so:
let error: Error?
switch error {
case .some(let error as NSError):
// error is non-nil and bridged to NSError
case .none:
// error is nil
}
Or, in my original code:
switch (error, status, data) {
case let (urlError as URLError, _, _):
done(.failure(.networkError(urlError.code)))
case let (.some(error as NSError), _, _):
done(.failure(.other(error)))
case let (_, _, data?) where data.containsGeoblockError():
done(.failure(.geoblocked))
case let (_, status?, data) where status.isFailure:
done(.failure(.httpError(status, data: data)))
case let (_, _, data):
done(.success(data))
}
However, it should work, non? Eg. the URLError
casting only works for non-nil values. Should this be reported as a bug?
(Tangential: Can URSession give some guarantees as to what kinds of errors that it will give. What non-URLError
s can I expect to get? Maybe I should ask that in the Apple Forums?)