Alamofire возвращает .Success по ошибке HTTP-коды состояния

У меня довольно простой сценарий, с которым я борюсь. Я использую Alamofire для регистрации пользователя в API для отдыха. Первый вызов для регистрации выполняется успешно, и пользователь может войти в систему. Второй вызов при попытке зарегистрировать с тем же адресом электронной почты должен привести к тому, что код состояния HTTP 409 будет отправлен с сервера. Alamofire, однако, возвращает .Success с пустым запросом и ответом. Я тестировал этот API с почтальоном, и он правильно возвращает 409.

Почему Alamofire не возвращается. Ошибка (ошибка), где ошибка имеет информацию о кодах состояния и т.д.?

Вот вызов, который я запускаю с тем же самым вводом каждый раз.

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)
    })

Ответ 1

Из руководства Alamofire :

Проверка

По умолчанию Alamofire рассматривает любой завершенный запрос, чтобы быть успешным, независимо от содержания ответа. Вызов подтверждения перед обработчик ответа вызывает возникновение ошибки, если ответ был неприемлемый код состояния или тип MIME.

Вы можете вручную проверить код состояния с помощью метода validate, опять же, из руководства:

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

Или вы можете полуавтоматически проверять код состояния и тип содержимого с помощью 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)
         }
     }

Ответ 2

Если вы используете response, вы можете проверить параметр NSHTTPURLResponse:

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

По умолчанию коды состояния 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
}

Или, если используется 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)
    }
}

Вышеупомянутый Alamofire 4.x. См. Предыдущее исполнение этого ответа для более ранних версий Alamofire.

Ответ 3

если вы используете validate(), вы потеряете сообщение об ошибке с сервера, если вы хотите сохранить его, см. этот ответ fooobar.com/info/455642/...