Alamofire returns .Success on error HTTP status codes

后端 未结 4 1077
北海茫月
北海茫月 2020-12-29 03:16

I have a pretty simple scenario that I\'m struggling with. I\'m using Alamofire to register a user on a rest API. The first call to register is successful and the user can l

相关标签:
4条回答
  • 2020-12-29 03:33

    Here is my code for AlamoFire error catching:

    switch response.result {
                    case .success(let value):
                        completion(.success(value))
                    case .failure(var error):
    
                        var errorString: String?
    
                        if let data = response.data {
                            if let json = try? (JSONSerialization.jsonObject(with: data, options: []) as! [String: String]) {
                                errorString = json["error"]
    
                            }
                        }
                        let error = MyError(str: errorString!)
                        let x = error as Error
                        print(x.localizedDescription)
                        completion(.failure(x))
    
                    }
    

    and the MyError class difinition:

    class MyError: NSObject, LocalizedError {
            var desc = ""
            init(str: String) {
                desc = str
            }
            override var description: String {
                get {
                    return "MyError: \(desc)"
                }
            }
            //You need to implement `errorDescription`, not `localizedDescription`.
            var errorDescription: String? {
                get {
                    return self.description
                }
            }
        }
    
    0 讨论(0)
  • 2020-12-29 03:34

    if you use validate() you'll loose the error message from server, if you want to keep it, see this answer https://stackoverflow.com/a/36333378/1261547

    0 讨论(0)
  • 2020-12-29 03:49

    From the Alamofire manual:

    Validation

    By default, Alamofire treats any completed request to be successful, regardless of the content of the response. Calling validate before a response handler causes an error to be generated if the response had an unacceptable status code or MIME type.

    You can manually validate the status code using the validate method, again, from the manual:

    Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
         .validate(statusCode: 200..<300)
         .validate(contentType: ["application/json"])
         .response { response in
             print(response)
         }
    

    Or you can semi-automatically validate the status code and content-type using the validate with no arguments:

    Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
         .validate()
         .responseJSON { response in
             switch response.result {
             case .success:
                 print("Validation Successful")
             case .failure(let error):
                 print(error)
             }
         }
    
    0 讨论(0)
  • 2020-12-29 03:50

    If using response, you can check the NSHTTPURLResponse parameter:

    Alamofire.request(urlString, method: .post, parameters: registrationModel.getParentCandidateDictionary(), encoding: JSONEncoding.default)
        .response { response in
            if response.response?.statusCode == 409 {
                // handle as appropriate
            }
    }
    

    By default, 4xx status codes aren't treated as errors, but you can use validate to treat it as an such and then fold it into your broader error handling:

    Alamofire.request(urlString, method: .post, parameters: registrationModel.getParentCandidateDictionary(), encoding: JSONEncoding.default)
        .validate()
        .response() { response in
            guard response.error == nil else {
                // handle error (including validate error) here, e.g.
    
                if response.response?.statusCode == 409 {
                    // handle 409 here
                }
                return
            }
            // handle success here
    }
    

    Or, if using responseJSON:

    Alamofire.request(urlString, method: .post, parameters: registrationModel.getParentCandidateDictionary(), encoding: JSONEncoding.default)
    .validate()
    .responseJSON() { response in
        switch response.result {
        case .failure:
            // handle errors (including `validate` errors) here
    
            if let statusCode = response.response?.statusCode {
                if statusCode == 409 {
                    // handle 409 specific error here, if you want
                }
            }
        case .success(let value):
            // handle success here
            print(value)
        }
    }
    

    The above is Alamofire 4.x. See previous rendition of this answer for earlier versions of Alamofire.

    0 讨论(0)
提交回复
热议问题