web-dev-qa-db-ja.com

Retrofit接続に失敗すると、RetrofitError.responseがnullとして返されます

Retrofit 1.6.0、OkHTTP 2.0.0、およびOkHTTP-UrlConnection2.0.0を使用します。

存在しないURLへのRetrofitを使用するサービスに対してPOSTを実行しています。予想どおり、失敗コールバックが呼び出されます。ただし、RetrofitErrorパラメーターに応答がありません。実際にを使用して返されたHTTPステータスコードを取得したい

error.getResponse().getStatus()

しかし、getResponse()はnullを返すため、できません。

GetResponse()がnullである理由と、ステータスを取得するにはどうすればよいですか?

ありがとう。

また、予想どおり、私が受け取っているエラーはUnknownHostExceptionです。繰り返します:私はこのエラーを予期しています。 HTTPステータスコードを取得する方法、またはerror.getResponse()がnullを返す理由を知りたいです。

編集:ここにいくつかのコードがあります:

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;
        }
    }
16
Marc

UnknownHostExceptionが発生した場合は、サーバーへの接続を確立できなかったことを意味します。実際、その場合、HTTPステータスを期待することはできません。

当然、サーバーに接続できる場合にのみ、Http応答(およびそのステータス)を取得します。

404ステータスコードを取得した場合でも、サーバーに接続しました。これはUnknownHostExceptionと同じではありません。

応答がない場合、getResponse()はnullを返す可能性があります。

10
lyio

RetrofitError にはisNetworkError()というメソッドがあり、ネットワークの問題が原因で失敗したリクエストを検出するために使用できます。私は通常、次のような小さなヘルパーメソッドを追加します。

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

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

次に、その結​​果を使用して、追加の障害ロジック(401でのログアウト、500でのエラーメッセージの表示など)を処理します。

7
swanson

@lyioの答えを拡張するために、Fabricロギングから、getKind()がUNEXPECTEDを返すことがあり、メッセージを解析するとタイムアウトと接続の問題が発生することがわかったので、以下にユーティリティクラスを作成しました。

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

私はRetrofit2を使用しています。エンドポイントのURLがあなたの場合のように「/」で終わり、インターフェースで再び「/」で始まる場合、[@ POST( "/ Login")]がこの問題を引き起こします。 .setEndpoint()メソッドから「/」を削除します

0
mustaq