ios Alamofire 返回 .Success 错误 HTTP 状态代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34737574/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Alamofire returns .Success on error HTTP status codes
提问by Craigt
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 log in. The second call, when trying to register with the same email address should result in a HTTP status code 409 from the server. Alamofire, however, returns a .Success with an empty request and response. I have tested this this API with postman and it correctly returns a 409.
我有一个非常简单的场景,我正在努力解决。我正在使用 Alamofire 在 rest API 上注册用户。第一次注册调用成功,用户可以登录。第二次调用,当尝试使用相同的电子邮件地址注册时,应该会导致来自服务器的 HTTP 状态代码 409。但是,Alamofire 会返回一个 .Success 并带有一个空的请求和响应。我已经用邮递员测试了这个 API,它正确地返回了 409。
Why is Alamofire not returning .Failure(error), where the error has status code info etc?
为什么 Alamofire 不返回 .Failure(error),其中错误具有状态代码信息等?
Here is the call I run with the same input each time.
这是我每次使用相同输入运行的调用。
Alamofire.request(.POST, "http://localhost:8883/api/0.1/parent", parameters: registrationModel.getParentCandidateDictionary(), encoding: .JSON).response(completionHandler: { (req, res, d, e) -> Void in
print(req, res, d, e)
})
回答by David Berry
From the Alamofire manual:
从 Alamofire手册:
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.
验证
默认情况下,Alamofire 将任何已完成的请求视为成功,而不管响应的内容如何。如果响应具有不可接受的状态代码或 MIME 类型,则在响应处理程序之前调用 validate 会导致生成错误。
You can manually validate the status code using the validate
method, again, from the manual:
您可以validate
再次使用手册中的方法手动验证状态代码:
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:
或者,您可以使用不validate
带参数的 半自动验证状态代码和内容类型:
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)
}
}
回答by Rob
If using response
, you can check the NSHTTPURLResponse
parameter:
如果使用response
,您可以检查NSHTTPURLResponse
参数:
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:
默认情况下,4xx 状态代码不被视为错误,但您可以validate
将其视为错误,然后将其折叠到更广泛的错误处理中:
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
:
或者,如果使用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.
以上是Alamofire 4.x。有关Alamofire 的早期版本,请参阅此答案的先前版本。
回答by Lilo
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
如果您使用validate(),您将从服务器丢失错误消息,如果您想保留它,请参阅此答案https://stackoverflow.com/a/36333378/1261547
回答by Payam Khaninejad
Here is my code for AlamoFire error catching:
这是我的 AlamoFire 错误捕获代码:
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:
和 MyError 类定义:
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
}
}
}