Home > Software design >  decoding empty array not throwing specified array
decoding empty array not throwing specified array

Time:03-30

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

  • Related