Decoding an Error Response using Alamofire 5 and the responseDecodable function

Viewed 13150

I'm writing an API Client for WooCommerce using Alamofire 5 (beta 1) which will allow me to get orders, coupons etc as well as create them. Note I am using the new .responseDecodable function.

I've set up my API client using the following performRequest function that looks like this:

@discardableResult
private static func performRequest<T:Decodable>(route: APIConfiguration,
                                                decoder: JSONDecoder = JSONDecoder(),
                                                completion: @escaping (Result<T>)->Void) -> DataRequest {
    return AF.request(route)
        .responseDecodable(decoder: decoder) { (response: DataResponse<T>) in
            completion(response.result)
    }
}

This works well, since I can, for instance, call a function getCouponForId(_ id: Int) which will execute this function and have the response returned through the completion handler.

The only downfall is that, say the user tries to access a coupon that does not exist, they will receive an error (404 from the server). I can switch on the result to determine either a success or failure case, but Alamofire attempts to decode the body of the error response into the Coupon model I have created.

Going forward, I have created an error model which I intend to have the error decoded using. But with that said, I'm having trouble implementing it into this function.

Does anyone have any ideas on how I could handle this?

(I have created this function through following this guide - hopefully, it might provide a bit more context to what I'm doing. https://github.com/AladinWay/NetworkingExample)

2 Answers

Similiar login function from the article you mentioned, updated for current beta of Alamofire 5 and dealing with 404, 401 etc. (via the guard statement)

  static func login(email: String, password: String, completion:@escaping (Result<UserCredentials>)->Void) {
    performRequest(router: Router.login(email: email, password: password), completion: completion)
    AF.request(Router.login(email: email, password: password))
      .validate(statusCode: 200..<300)
      .responseDecodable { (response: DataResponse<UserCredentials>) in
        guard response.result.isSuccess else {
          print(" Error on login: \(String(describing: response.error))")
          return
        }
        completion(response.result)
    }
  }

Just update

request.responseDecodable(decoder: decoder, completionHandler: { (response: AFDataResponse<T>) in

to

request.responseDecodable(decoder: decoder, completionHandler: { (response: DataResponse<T>) in
Related