Ошибка подключения дооснащения RetrofitError.response как null

Использование Retrofit 1.6.0, OkHTTP 2.0.0 и OkHTTP-UrlConnection 2.0.0.

Я делаю POST для службы, используя Retrofit, к URL-адресу, который не существует. Вызывается обратный вызов отказа, как и ожидалось. Однако параметр 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;
        }
    }

Ответы

Ответ 1

Когда вы получаете событие UnknownHostException, это означает, что вы не смогли установить соединение с сервером. В этом случае вы не можете ожидать статуса HTTP.

Естественно, вы можете получить ответ Http (и с этим статусом), когда вы можете подключиться к серверу.

Даже когда вы получаете код состояния 404, вы подключились к серверу. Это не то же самое, что и UnknownHostException.

Функция getResponse() может возвращать значение null, если вы не получили ответ.

Ответ 2

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 и т.д.).

Ответ 3

Я использую Retrofit 2. Когда endpoint url заканчивается на "/" , как в вашем случае, и снова в вашем интерфейсе он начинается с "/" [@POST ( "/Login" )] вызывает эту проблему. Удалите "/" из метода .setEndpoint()

Ответ 4

Просто чтобы расширить ответ на @lyio, я обнаружил, что 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;
}

}