I have RestManager class for fetching data from Internet.
I wanted to made special case when empty array is decoded function returns error.
So I made this
class RestManager {
func fetchData<T: Decodable>(url: URL) -> AnyPublisher<T, ErrorType> {
URLSession
.shared
.dataTaskPublisher(for: url)
.tryMap { data, _ in
let value = try JSONDecoder().decode(T.self, from: data)
if let array = value as? [AnyObject], array.isEmpty {
throw ErrorType.empty
}
return value
}
.mapError { error -> ErrorType in
switch error {
case is Swift.DecodingError:
return ErrorType.empty
case let urlError as URLError:
switch urlError.code {
case .notConnectedToInternet, .networkConnectionLost, .timedOut:
return .noInternetConnection
case .cannotDecodeRawData, .cannotDecodeContentData:
return .empty
default:
return .general
}
default:
return .general
}
}
.eraseToAnyPublisher()
}
}
But the problem is that returning ErrorType is .general instead of .empty
CodePudding user response:
First of all a JSON array is never a reference type like [AnyObject]
, a decoded array is [Any]
.
The unexpected behavior occurs because you don't consider ErrorType
in the mapError
body. If an empty array is being decoded the thrown ErrorType.empty
is neither a DecodingError
nor an URLError
so the default case .general
is returned