web-dev-qa-db-fra.com

Alamofire renvoie .Succès sur les codes d'état HTTP d'erreur

J'ai un scénario assez simple avec lequel je me bats. J'utilise Alamofire pour enregistrer un utilisateur sur une API de repos. Le premier appel à l'enregistrement a réussi et l'utilisateur peut se connecter. Le deuxième appel, lorsqu'il essaie de s'enregistrer avec la même adresse e-mail, doit générer un code d'état HTTP 409 du serveur. Alamofire, cependant, renvoie un .Success avec une demande et une réponse vides. J'ai testé cette API avec postman et elle renvoie correctement un 409.

Pourquoi Alamofire ne retourne pas .Failure (erreur), où l'erreur contient des informations sur le code d'état, etc.?

Voici l'appel que je lance avec la même entrée à chaque fois.

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

Depuis l'Alamofire manuel :

Validation

Par défaut, Alamofire traite toute demande terminée pour qu'elle aboutisse, quel que soit le contenu de la réponse. L'appel de validate avant qu'un gestionnaire de réponse provoque la génération d'une erreur si la réponse avait un code d'état ou un type MIME inacceptable.

Vous pouvez valider manuellement le code d'état à l'aide de la méthode validate, encore une fois, à partir du manuel:

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

Ou vous pouvez valider semi-automatiquement le code d'état et le type de contenu en utilisant le validate sans 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)
         }
     }
65
David Berry

Si vous utilisez response, vous pouvez vérifier le paramètre NSHTTPURLResponse:

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

Par défaut, les codes d'état 4xx ne sont pas traités comme des erreurs, mais vous pouvez utiliser validate pour le traiter comme tel, puis le replier dans votre gestion d'erreurs plus large:

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
}

Ou, si vous utilisez 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)
    }
}

Ce qui précède est Alamofire 4.x. Voir le rendu précédent de cette réponse pour versions antérieures d'Alamofire .

14
Rob

si vous utilisez validate () vous perdrez le message d'erreur du serveur, si vous voulez le garder, voyez cette réponse https://stackoverflow.com/a/36333378/1261547

5
Lilo