Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to determine Error response from Swift.Result and Enum

I created a method that uses Swift.Result to return an image and an Error from a URLSession. I also created an Enum for the errors.

When a Swift.Result error is returned, how can I tell the difference between the 4 enums?

fetchImage(with: url) { (result) in
    switch result {

    case .failure(let err):
        print(err)

        // how can I determine which of the 4 enum errors was returned?

        /* Example
        if failErr { ... }
        if responseStatusCodeErr { ... }
        if dataIsNil { ... }
        if catchErr { ... }
        */

    case .success(let img):
        // ...
    }
}

Enum:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

enum SessionDataTaskError: Error {
    
    case failErr(Error)
    case responseStatusCodeErr(Int)
    case dataIsNil
    case catchErr(Error)
}

URLSession:

fetchImage(with url: URL, completion: @escaping (Swift.Result<[UIImage], Error>)->Void) {

    URLSession.shared.dataTask(with: url) { (data, res, error) in

        if let error = error {
            completion(.failure(SessionDataTaskError.failErr(error)))
            return
        }
    
        if let response = res as? HTTPURLResponse {
            guard 200 ..< 300 ~= response.statusCode else {
                completion(.failure(SessionDataTaskError.responseStatusCodeErr(response.statusCode)))
                return
            }
        }
    
        guard let data = data else {
            completion(.failure(SessionDataTaskError.dataIsNil))
            return
        }
    
        do {

            // all good ...

        } catch {

            completion(.failure(SessionDataTaskError.catchErr(error)))
        }
    }.resume()
}

>Solution :

First, I would change your completion handler to only take SessionDataTaskError as the error type of the Result, because you never call it with any other types of Error:

func fetchImage(with url: URL, 
    completion: @escaping (Swift.Result<[UIImage], SessionDataTaskError>)->Void) {

Then, you can use pattern matching to match the 4 cases of errors:

fetchImage(with: url) { (result) in
    switch result {
    case .failure(let error):
        print(error)
        switch error {
        case .failErr:
            // ...
        case .responseStatusCodeErr:
            // ...
        case .dataIsNil:
            // ...
        case .catchErr:
            // ...
        }
    case .success(let img):
        // ...
    }
}

If in every case you do different things, you can avoid the nested switch by doing:

fetchImage(with: url) { (result) in
    switch result {

    case .failure(.failErr):
        // ...
    case .failure(.responseStatusCodeErr):
        // ...
    case .failure(.dataIsNil):
        // ...
    case .failure(.catchErr):
        // ...
    case .success(let img):
        // ...
    }
}

If there are different types of errors that fetchImage can produce and you just want to check for the four SessionDataTaskErrors, you can use a type pattern let error as SessionDataTaskError, and add an extra case to handle other kinds of errors.

fetchImage(with: url) { (result) in
    switch result {
    case .failure(let error as SessionDataTaskError):
        print(error)
        switch error {
        case .failErr:
            // ...
        case .responseStatusCodeErr:
            // ...
        case .dataIsNil:
            // ...
        case .catchErr:
            // ...
        }
    case .failure(let otherError):
        print("Other Error:", otherError)
    case .success(let img):
        // ...
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading