immobiliare / RealHTTP

🌀swift async http client - fast, lightweight, type-safe
MIT License
282 stars 28 forks source link

How to handle errors in RealHTTP: a test case #64

Open bhartsb opened 2 years ago

bhartsb commented 2 years ago

Hello, I did a take-home exercise for Walmart Labs and decided to use RealHTTP after doing a quick compare to other HTTP clients. My take-home was rejected and one of the three reasons was it "doesn't handle errors in a nice way". I didn't really handle errors as it was outside of the scope and 60 minute timeframe, but I did put in a catch:

struct APIService {

    struct InfoService {
        static func fetchCountries() async ->CountryInfo?  {
            do {
                guard let url = URL(string: "\(APIEnvironment.development.baseURL)/peymano-wmt/32dcb892b06648910ddd40406e37fdab/raw/db25946fd77c5873b0303b858e861ce724e0dcd0/countries.json") else { throw "Malformed URL" }
                if let countryInfo = try await HTTPRequest(url)
                    .fetch(CountryInfo.self) {
                    return countryInfo
                }
            } catch {
                //TODO: log error
            }
            return nil
        }
    }
}

class CapitalSearchViewModel {
    weak var dataSource : GenericDataSource<CountryInfoElement>?

    init(dataSource : GenericDataSource<CountryInfoElement>?) {
        self.dataSource = dataSource
    }

    func fetchCountries() {
        Task {
            await self.dataSource?.data.value = APIService.InfoService.fetchCountries() ?? []
        }
    }
}

Extending on what is above, what would be the preferred way to do error handling with RealHTTP? I can provide access to the project if anyone wants to take a look. I didn't really agree with the feedback and would appreciate more opinions from other iOS devs if anyone has time. My email is bhartsb at gmail.com. The other feedback was "iOS code is overly complex" and "boilerplate code". Boiler plate code was Xcode generated for the most part.

nashfive commented 2 years ago

Not sure how to respond to that since we only have a tiny portion of your code, so I can't comment on the complexity/boilerplate matter.

Regarding your error handling, there are many ways to do it, but from what I read in your example is that the error is silently swallowed and your user would never know why there are no results. What I would have done is let the service throw the errors and handle (catch) it in the ViewModel, so that it can make the view could at least display a reason.

malcommac commented 2 years ago

If you could upload an example project, I could help you decide the best strategy. Error handling can be done using validators or checking the HTTPResponse returned by your service, which exposes all the standard info of any HTTP.

bhartsb commented 2 years ago

@malcommac Sorry for the delay. Here is a project. CountryDigest.zip