web-dev-qa-db-fra.com

L'échec de la connexion de conversion retourne RetrofitError.response comme null

Utilisation de Retrofit 1.6.0, OkHTTP 2.0.0 et OkHTTP-UrlConnection 2.0.0.

Je fais un POST à un service utilisant Retrofit vers une URL qui n'existe pas. Le rappel d'échec est appelé, comme prévu. Cependant, le paramètre RetrofitError n'a pas de réponse. Je voudrais vraiment saisir le code de statut HTTP qui a été renvoyé à l'aide de

error.getResponse().getStatus()

mais puisque getResponse () renvoie null, je ne peux pas.

Pourquoi getResponse () est null et comment puis-je obtenir le statut?

Merci.

En outre, l'erreur que je reçois est UnknownHostException, comme prévu. Répétez: je m'attends à cette erreur. Je veux savoir comment obtenir le code de statut HTTP ou pourquoi error.getResponse () renvoie la valeur null.

Edit: Voici du code:

RestAdapterBuilderClass.Java
    RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("http://badURL.DoesntMatter/");
            .setRequestInterceptor(sRequestInterceptor)
            .setLogLevel(RestAdapter.LogLevel.FULL)
             .build();
    sService = restAdapter.create(ServiceInterface.class);

ServiceInterface.Java
    @POST("/Login")
    void login(@Body JsonObject body, Callback<String> callback);

CallbackClass.Java
    @Override
    public void failure(RetrofitError error) {
        if (error.getResponse() == null) {

            // error.getResponse() is null when I need to get the status code
            // from it.

            return;
        }
    }
14
Marc

Lorsque vous obtenez une UnknownHostException, cela signifie que vous n’avez pas pu établir de connexion au serveur. En fait, vous ne pouvez pas vous attendre à un statut HTTP dans ce cas.

Naturellement, vous n’obtenez une réponse HTTP (et donc un statut) lorsque vous pouvez vous connecter à un serveur.

Même lorsque vous obtenez un code d'état 404, vous vous êtes connecté au serveur. Ce n'est pas la même chose qu'une exception UnknownHostException.

La méthode getResponse () peut renvoyer null si vous n'avez pas reçu de réponse.

9
lyio

RetrofitError a une méthode appelée isNetworkError() que vous pouvez utiliser pour détecter une demande ayant échoué en raison de problèmes de réseau. J'ajoute généralement une petite méthode d'assistance comme celle-ci:

public int getStatusCode(RetrofitError error) {
    if (error.isNetworkError()) {
        return 503; // Use another code if you'd prefer
    }

    return error.getResponse().getStatus();
}

puis utilisez ce résultat pour gérer toute logique d'échec supplémentaire (déconnexion sur 401, affichage du message d'erreur sur 500, etc.).

7
swanson

Juste pour développer la réponse de @ lyio, j'ai trouvé dans la journalisation Fabric que getKind () renvoyait parfois UNEXPECTED, puis si vous analysez le message, vous obtenez des délais d'attente et des problèmes de connexion. J'ai donc écrit la classe utilitaire ci-dessous.

public class NetworkUtils {
    // Compiled from Fabric events
    private static final List<String> networkErrorStrings = new ArrayList<>(Arrays.asList(
        "Unable to resolve Host",
        "Connection closed by peer",
        "Failed to connect",
        "timeout",
        "Connection timed out"));

    public static boolean isNetworkError(@Nullable RetrofitError retrofitError) {
        if (retrofitError != null) {
            if (retrofitError.getKind() != RetrofitError.Kind.NETWORK) {
                for (String error : networkErrorStrings) {
                    if (retrofitError.getMessage().contains(error)) {
                        return true;
                    }
                }
            } else {
                return true;
            }
        }

        return false;
}

}

1
Peter File

J'utilise Retrofit 2. Lorsque l'URL du noeud final se termine par "/" comme dans votre cas et dans votre interface, il commence par "/" [@POST ("/ Login")] est la cause de ce problème. Supprimez le "/" de la méthode .setEndpoint ()

0
mustaq