Retrofit2 httpexception http 500 internal server error

I get a HTTP 500 INTERNAL SERVER ERROR on a POST using RXJAVA and RETROFIT and I dont fully understand how this Call works, but the other Call is working fine, with the same BASE_URL constant. Her...

I get a HTTP 500 INTERNAL SERVER ERROR on a POST using RXJAVA and RETROFIT and I dont fully understand how this Call works, but the other Call is working fine, with the same BASE_URL constant.

Here is my interface:

public interface AuthApi {

    @GET("user/{id}")  //users/id
    Flowable<User> getUser(
            @Path("id") int id
    );

    @POST("login")
    @FormUrlEncoded
    Flowable<User> login(
            @Field("username") String username,
            @Field("password") String password
    );
}

The @GET Method works fine
The @POST Method returns an error

I believe this has something to do, with how the string or post request is getting structured, because Postman is working perfectly with following json:

{
    "username": "Test1",
    "password": "test1"
}

Here is the the rxjava call:

authApi.login("Test1","test1")
                .toObservable()
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<User>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(User user) {
                        Log.d(TAG,"onNext :"+ user.getEmail());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "onError: ", e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });

This returns the HTTP 500 INTERNAL SERVER ERROR

But to give you guys more details, here is the error log:

E/AuthViewModel: onError: 
    retrofit2.adapter.rxjava2.HttpException: HTTP 500 INTERNAL SERVER ERROR
        at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onNext(BodyObservable.java:54)
        at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onNext(BodyObservable.java:37)
        at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:47)
        at io.reactivex.Observable.subscribe(Observable.java:10838)
        at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
        at io.reactivex.Observable.subscribe(Observable.java:10838)
        at io.reactivex.internal.operators.flowable.FlowableFromObservable.subscribeActual(FlowableFromObservable.java:29)
        at io.reactivex.Flowable.subscribe(Flowable.java:12978)
        at io.reactivex.internal.operators.flowable.FlowableOnBackpressureLatest.subscribeActual(FlowableOnBackpressureLatest.java:32)
        at io.reactivex.Flowable.subscribe(Flowable.java:12978)
        at io.reactivex.Flowable.subscribe(Flowable.java:12924)
        at io.reactivex.internal.operators.observable.ObservableFromPublisher.subscribeActual(ObservableFromPublisher.java:31)
        at io.reactivex.Observable.subscribe(Observable.java:10838)
        at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
        at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:452)
        at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
        at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)

This is the expected response:

{
    "email": "test1m@test1.ie",
    "id": 11,
    "username": "Test1"
}

Do I overlook something? do you guys have any tips for me?
And is there a way to debug the POSt request to actualy see the POSt request?

Содержание

  1. retrofit2.adapter.rxjava2.HttpException: HTTP 500 Internal Server Error #5750
  2. Comments
  3. retrofit2.adapter.rxjava2.HttpException HTTP 500 Server Error #2842
  4. Comments
  5. io.reactivex.exceptions.OnErrorNotImplementedException:HTTP 500 Server Error
  6. Footer
  7. [Question] Does 500 internal server error get routed to onError in a subscriber? #2203
  8. Comments
  9. Ошибка 500 Internal Server Error: что это и как её исправить
  10. Ошибка 500 Internal Server Error — диагностика
  11. Ошибка 500 Internal Server Error — устранение на популярных платформах
  12. Ошибка 500 Internal Server Error — устранение на стороне серверных скриптов
  13. Попросите помощи у системного администратора
  14. Ошибку 500 Internal Server Error довольно легко устранить
  15. error: retrofit2.adapter.rxjava2.HttpException: HTTP 404 Not Found #2815
  16. Comments

retrofit2.adapter.rxjava2.HttpException: HTTP 500 Internal Server Error #5750

: retrofit2.adapter.rxjava2.HttpException: HTTP 500 Internal Server Error
at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onNext(BodyObservable.java:54)
at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onNext(BodyObservable.java:37)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:43)
at io.reactivex.Observable.subscribe(Observable.java:10901)
at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
at io.reactivex.Observable.subscribe(Observable.java:10901)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:452)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)

The text was updated successfully, but these errors were encountered:

Источник

retrofit2.adapter.rxjava2.HttpException HTTP 500 Server Error #2842

io.reactivex.exceptions.OnErrorNotImplementedException:HTTP 500 Server Error

io.reactivex.exceptions.OnErrorNotImplementedException:HTTP 500 Server Error

2 io.reactivex.internal.functions.Functions$m.a(Functions.java:704)
3 .
4 Caused by:
5 retrofit2.adapter.rxjava2.HttpException:HTTP 500 Server Error
6 retrofit2.adapter.rxjava2.a$a.a(BodyObservable.java:54)
7 retrofit2.adapter.rxjava2.a$a.onNext(BodyObservable.java:37)
8 retrofit2.adapter.rxjava2.c.a(CallExecuteObservable.java:43)
9 io.reactivex.r.subscribe(Observable.java:11040)
10 retrofit2.adapter.rxjava2.a.a(BodyObservable.java:34)
11 io.reactivex.r.subscribe(Observable.java:11040)
12 io.reactivex.internal.operators.observable.ObservableSubscribeOn$a.run(ObservableSubscribeOn.java:96)
13 io.reactivex.x$a.run(Scheduler.java:463)
14 io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
15 io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
16 java.util.concurrent.FutureTask.run(FutureTask.java:266)
17 java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
18 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
19 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
20 java.lang.Thread.run(Thread.java:764)

The text was updated successfully, but these errors were encountered:

An HTTP 500 is an error from your server and OnErrorNotImplementedException means you didn’t implement an error callback when subscribing.

© 2023 GitHub, Inc.

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Источник

[Question] Does 500 internal server error get routed to onError in a subscriber? #2203

I have a very basic retrofit setup like below.

I just ran into a issue where the onError in a subscriber does not get invoked if the server returns a 500 error response code.

Is it the normal behaviour? Or are there any special handling that needs to be done so that all none 2xx responses invokes the onError of a subscriber?

The text was updated successfully, but these errors were encountered:

By declaring a type of Observable > you’re indicating to Retrofit that you want onNext to be called with all HTTP responses and only call onError when the network or serialization fails. If you want non-200 status codes to call onError then you should declare Observable . If you need the information from Response but want a 5xx status code to error then you can either write a custom CallAdapter for this behavior (which is hard) or just apply a map operation that checks the status code and manually throws an HttpException .

@JakeWharton Thanks for the quick answer. I just have some more questions.

In my code, i have a couple types..

I have done Observable I notice this will call onError for 500 status code.

I have also done Observable and this does not call onError .

Are these all expected? What criteria needs to be met for onError to be invoked? Judging by your reply, network and serialization fail will trigger onError. So does that mean MySimpleJSONModel actually serialized properly given my 500 server error response?

I only have these two factories for the retrofit builder.

Источник

Ошибка 500 Internal Server Error: что это и как её исправить

Разработчики и люди, профессионально работающие с веб-приложениями, боятся 500 Internal Server Error . Оптимальный способ её устранения зависит от сервера и того, что на нём запущено. В данной статье приводятся советы по диагностике и исправлению ошибки 500 .

Ошибка 500 Internal Server Error — диагностика

Важно помнить, что эта ошибка происходит на стороне сервера. Это значит, что HTML-код , выполняемый на стороне клиента, а также JavaScript или любые другие запущенные в браузере объекты, не могут быть причиной, по которой возникает ошибка 500 Internal Server Error . Само название ( Internal Server Error – ‘внутренняя ошибка сервера’ ) говорит о том, что ошибка происходит на сервере.

Ошибка 500 Internal Server Error — устранение на популярных платформах

Многие пользователи устанавливают на свой сервер популярные CMS-системы , такие как WordPress , Joomla , Drupal и они не должны вызывать ошибку 500 , если всё настроено правильно. Однако она всё равно всплывает – из-за несовместимости версий, некачественных установок или сбоя прав доступа на сервере.

Вот некоторые распространённые проблемы, которые могут вызывать подобную ошибку в часто используемых CMS :

  • Если вы только что обновили движок до новой версии, вероятно, обновление прошло с ошибками и необходимо провести его повторно. Скорее всего, на сайте разработчика есть инструкции, как это правильно сделать.
  • Если вы только что активировали новый плагин или новую тему, стоит попробовать отменить эти изменения. Даже профессионально написанные плагины могут конфликтовать с другими и вызывать 500 Internal Server Error nginx
  • Если вы обновляли CMS , старые плагины и темы могут быть с ней несовместимы. Единственное, что можно сделать в таком случае — отключать их по очереди, пока ошибка 500 не исчезнет.
  • Неправильно заданные права доступа на сервере или ошибки в файле .htaccess . Серверу не удаётся получить доступ к скриптам, файлам и другим ресурсам, поэтому он выдаёт ошибку.

Когда причиной, по которой возникает ошибка 500 Internal Server Error являются скрипты и плагины, лучше всего искать ответы на сайтах их разработчиков.

Ошибка 500 Internal Server Error — устранение на стороне серверных скриптов

Другой причиной по которой может возникнуть ошибка 500 Internal Server Error может стать разработка и тестирование собственных скриптов.

Чтобы справиться с такой ошибкой, попробуйте следующие решения :

  • Настройка прав на сервере : часто неверная настройка прав доступа к файлу или папке приводит к тому, что сервером выдаётся ошибка 500 Internal Server Error . Из-за того, что ему не удаётся запустить скрипт. Выясните, какие права должны быть настроены, и выставьте их соответствующим образом.
  • Превышено время ожидания : возможно, истекло время ожидания ответа от PHP или другого серверного скрипта. Это происходит из-за того, что недоступен определённый ресурс или коде была допущена ошибка, запускающая бесконечный цикл.
  • Превышено время ожидания соединения с сервером: если сервер был занят, перезагружался или потерял соединение, скрипт может выдать ошибку 500 Internal Server Error . Возможно, в следующий раз ошибки не будет. Но если ошибка появляется при тестировании, велика вероятность того, что она встретится и пользователям.
  • Ошибки в файле .htaccess: в некоторых случаях ошибку 500 может вызывать код, прописанный в файле .htaccess .
  • Ошибки в скрипте: если ошибку выдаёт скрипт, можете запросить у него подробную информацию об ошибке. К примеру, в PHP можно включить вывод ошибок на экран или в лог-файл, добавив директиву display_errors . По умолчанию среда выполнения может скрывать ошибки, но это не очень удобно для отладки программы.

Попросите помощи у системного администратора

В некоторых случаях у разработчиков нет полного контроля над сервером.

Если скрипт запускается на сервере сторонней организации, она может помочь вам в следующем :

  • Предоставить документацию о своём сервере и возможных причинах ошибки 500 . В зависимости от используемой операционной системы и настройки оборудования, данная ошибка может возникать по разным причинам.
  • Попросите службу поддержки хостинга посмотреть лог-файлы с ошибками — системный администратор сможет определить, был ли сервер во время возникновения ошибки загружен или вовсе « упал ».

Ошибку 500 Internal Server Error довольно легко устранить

Ошибка 500 Internal Server Error — как исправить ? В большинстве случаев причины возникновения ошибки 500 легко исправляются. Проблема заключается в том, что без конкретной информации определение причины возникновения сбоя усложняется. Легче всего справиться с ошибкой, когда разработчик выяснит, что изменилось перед возникновением ошибки.

Не забывайте, что произошедшие изменения могли быть осуществлены и другими людьми — например, администратором сервера. Если же ничего не менялось, вероятно, сам сервер стал причиной возникновения ошибки из-за несовместимости программного обеспечения или проблем с производительностью.

Вадим Дворников автор-переводчик статьи « 500 Internal Server Error: What It Is And How To Fix It »

Источник

error: retrofit2.adapter.rxjava2.HttpException: HTTP 404 Not Found #2815

when i use rxjava i got this error

error: retrofit2.adapter.rxjava2.HttpException: HTTP 404 Not Found
at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onNext(BodyObservable.java:54)
07-02 23:53:39.876 18974-20433/com.susham.salamtk W/System.err: at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onNext(BodyObservable.java:37)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:44)
at io.reactivex.Observable.subscribe(Observable.java:12036)
at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
at io.reactivex.Observable.subscribe(Observable.java:12036)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:579)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
07-02 23:53:39.876 18974-20433/com.susham.salamtk W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
07-02 23:53:39.877 18974-20433/com.susham.salamtk W/System.err: at java.lang.Thread.run(Thread.java:818)

this is my configration

without rxjava adapter it works fine i try it both in the same activity to be sure it work

@get(«api/Ambulancetypes»)
fun getAmbulanceTypes(): Observable

//

private val builder = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient.build())
var retrofit = builder.build()

//
apiService.getAmbulanceTypes()
.subscribeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponse, this::handleError)

ext <
retrofit_version = «2.4.0»
>

The text was updated successfully, but these errors were encountered:

Источник

Введение

Я думаю, что большинство маленьких партнеров теперь используют OKHTTP или модернизацию для выполнения сетевых запросов, в конце концов, Squar получит бутик. Не прозрачна, сегодня стоит поговорить о HTTP запрашивать звуковой код. Все знают, что запрос на Android реализуется по HttpUurLConnection (httpClient уже отбрасывается в последнем исходном коде Google), после запуска сетевого запроса, произойдет объект ответа для возврата к информации о ответе, и только в ответе 200 Настало время к успеху, 400 — запрашиваемый URL, содержащий нелегальные символы, 404 — запрашиваемый URL-адрес не существует, 500 — ошибка внутри сервера.

Ниже придает примерно классификацию

Код состояния Категория ответов Описание
1XX Информационный код состояния Сервер обрабатывает запрос
2XX Успешный код статуса Запрос был обработан нормально
3XX Код состояния перенаправления Извлечение необходимо завершить запрос
4XX Код состояния ошибки клиента Клиентские причины приводят к невозможности обработки запросов
5XX Код состояния ошибки сервера Причины сервера приводят к ошибке запроса на ответ

Android Http код ответа кода код состояния

Во-вторых, метод общих модернизации + RXJAVA запрос заключается в следующем

mModel.getOneDayTempData(timestamp)
                .subscribe(new Observer<TemperatureBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        
                    }

                    @Override
                    public void onNext(TemperatureBean temperatureBean) {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

Если ответ успешна, код ответа составляет 200, onnelex будет выполнен, если код ответа не является 200, а oneRror () может быть выполнен, а информация отклика может быть получена при annnext (), это все знают. Отказ Но когда ответ не удается, параметры метода OnLineerowable E) являются моторируемым объектом, и мы распечатаем результаты через e.tostring ().

Я намеренно отправил неправильный запрос, и результат просто печатает информацию заголовка, и ответа мы не хотим.

retrofit2.adapter.rxjava2.HttpException: HTTP 500 Internal Server Error

Здесь я более хлопотно, согласно httpurLConnection, даже если это 500, я могу получить этот ответ, я хочу быть этой мочеиспускательной информацией, то я думаю, что есть с модернизации OKHTTP, я буду использовать OKHTTP. Попробуй

OkHttpUtils.doPostRequest(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                
            }

            @Override
            public void onResponse(Call call, Response response) {
                String body = response.body().string();
                Log.i(TAG, "onResponse: "+body);
            }
        });

Конечно, информация о теле, когда вы получаете код 500 в этом ответе

Так что теперь до тех пор, пока я преобразую OneRor (Thumbable E), чтобы ответить, не так ли? В это время проверьте исходный код, исключение унаследовано в makable, поэтому я увижу исходный код этого httpException.
HttpException Part Source код

public class HttpException extends Exception {
  private static String getMessage(Response<?> response) {
    if (response == null) throw new NullPointerException("response == null");
    return "HTTP " + response.code() + " " + response.message();
  }

  private final int code;
  private final String message;
  private final transient Response<?> response;

  public HttpException(Response<?> response) {
    super(getMessage(response));
    this.code = response.code();
    this.message = response.message();
    this.response = response;
  }
}

Конечно, у меня есть код кода и ответа, который я хочу, поэтому я просто делаю это, мне просто нужно повернуть другую к httpException, чтобы получить информацию.

Путь вниз выглядит следующим образом

 if (throwable instanceof HttpException){
          ResponseBody body = ((HttpException) throwable).response().errorBody();
          try {
                 Log.i(TAG, "onFailure: "+body.string());
             } catch (IOException e) {
                  e.printStackTrace();
             }
        }

Справочная информация моей компании имеет какой-то ErrorCode и ErroRORMSG в этой информации о исключительной информации, размещенной в 500, я должен иметь дело с этим OneRor (Mourcable E), получить информацию в этом для подсказки пользователей, чтобы укрепление программы может гарантировать надежность программы программа. Хорошо, я надеюсь помочь тем же друзьям!

When we introduced our API error handler we threw all possible non-success responses from the server in one bucket and handled them the same way.

But this might not be the best idea. For example, a server response with status code 404 indicates that the resource we’re trying to access is not available (anymore). On the contrary, a server response of status code 500 indicates that the server itself ran into an error. These two errors should be handled differently.

In this tutorial, we’ll show you how you can globally deal with a certain type of error, e.g., expired auth tokens from 401 responses or broken server responses with 5xx as the status code.

Retrofit Series Overview

  • Retrofit
  • Requests
  • Responses
  • Converters
  • Error Handling
  • Logging
  • Calladapters
  • Pagination
  • File Upload & Download
  • Authentication
  • Caching
  • Testing & Mocking
  • Java Basics for Retrofit

Distinguish Server Error Responses

For the next few minutes we’ll assume your server is compliant with HTTP standards and sends appropriate status codes, e.g., 404 for resources not found. In the Retrofit’s onResponse() callback you’ve access to the response status code via the response.code() method.

A simple solution would be to check this code in the error scenario and act accordingly:

call.enqueue(new Callback<List<GitHubRepo>>() {  
    @Override
    public void onResponse(Call<List<GitHubRepo>> call, Response<List<GitHubRepo>> response) {
        if (response.isSuccessful()) {
            Toast.makeText(ErrorHandlingActivity.this, "server returned so many repositories: " + response.body().size(), Toast.LENGTH_SHORT).show();
            // todo display the data instead of just a toast
        }
        else {
            // error case
            switch (response.code()) {
                case 404:
                    Toast.makeText(ErrorHandlingActivity.this, "not found", Toast.LENGTH_SHORT).show();
                    break;
                case 500:
                    Toast.makeText(ErrorHandlingActivity.this, "server broken", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(ErrorHandlingActivity.this, "unknown error", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }

    @Override
    public void onFailure(Call<List<GitHubRepo>> call, Throwable t) {
        Toast.makeText(ErrorHandlingActivity.this, "network failure :( inform the user and possibly retry", Toast.LENGTH_SHORT).show();
    }
});

While this would work, it’s quite inefficient. You would have to copy and paste this code into every single response callback. Especially when you want to change the behavior this quickly turns into a nightmare. Even if you move the logic into a central method, you would have to remember to call this method in every single response callback.

The best way to deal with global error scenarios is to handle them in one central place for all requests: an OkHttp interceptor.

Global Error Handler: OkHttp Interceptor

We’ve used OkHttp interceptors to act globally within the app in previous tutorials, for example to add query parameters to every request. The difference to this time is that we’re intercepting the request on it’s way back. Instead of modifying the request, we’re intercepting the server response! Specifically, we take a look at the status code and, if it’s a status code of 500, we open a separate activity to inform the user that the servers are currently unavailable. The user won’t be able to further interact with the app and run into even more undefined behavior.

The way we add a response interceptor is almost the same as adding the request interceptors we’ve used before:

OkHttpClient okHttpClient = new OkHttpClient.Builder()  
        .addInterceptor(new Interceptor() {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                okhttp3.Response response = chain.proceed(request);

                // todo deal with the issues the way you need to
                if (response.code() == 500) {
                    startActivity(
                            new Intent(
                                    ErrorHandlingActivity.this,
                                    ServerIsBrokenActivity.class
                            )
                    );

                    return response;
                }

                return response;
            }
        })
        .build();

Retrofit.Builder builder = new Retrofit.Builder()  
        .baseUrl("http://10.0.2.2:3000/")
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create());

Retrofit retrofit = builder.build();  

As you can see in the snippet above, the okhttp3.Response response = chain.proceed(request); line accesses the server response. Consequently, we can check the status code with if (response.code() == 500) and then open the ServerIsBrokenActivity.

Depending on your use case and the requirements you’ll need to adjust this behavior and the possible status codes to your scenario. Also, just as a heads-up, the response will still arrive at the callback! Make sure you are not configuring conflicting app behavior.

The advantage of this approach is: every request made with the retrofit object will deal with the error in the same way. You only have a single place for all major error handling. We recommend moving this into the ServiceGenerator as well. Fantastic!

Summary

In this tutorial you’ve learned how you can use a response interceptor to globally catch server errors. You can significantly increase the quality of your app when you deal with error scenarios the right way. Don’t cut corners here!

Do you have further questions on this topic or about Retrofit in general? Just let us know on Twitter @futurestud_io or leave a comment below.

Enjoy coding & make it rock!

Still Have Questions? Get Our Retrofit Book!

Retrofit Book

All modern Android apps need to do network requests. Retrofit offers you an extremely convenient way of creating and managing network requests. From asynchronous execution on a background thread, to automatic conversion of server responses to Java objects, Retrofit does almost everything for you. Once you’ve a deep understanding of Retrofit, writing complex requests (e.g., OAuth authentication) will be done in a few minutes.

Invest time to fully understand Retrofit’s principles. It’ll pay off multiple times in the future! Our book offers you a fast and easy way to get a full overview over Retrofit. You’ll learn how to create effective REST clients on Android in every detail.

Boost your productivity and enjoy working with complex APIs.

During app development, We have always faced errors and exceptions and crashes due to APIs failures. As a native mobile developer, it very important to ensure the app never crashes at the end-user. You guys also aware Retrofit with RxJava is mostly used for calling external APIs In this tutorials, I’m going to write a solution to retrofit handle error in android while integrating external APIs in a single place.

Basically, the mobile application is dependent on the API development process and doesn’t guarantee the APIs response will be always expected. If the problem is backend then they prepare a patch of containing bug fix and deployed. But in the mobile app development, it’s not happened. You depend on review times of Google Play/App Store if you need to quickly deploy a patch containing a bug fix. In this case, you also need your users to update the app after the approval to get it fixed.

The following API instability occur while integrating Rest APIs

  1. NullPointerException
  2. Manage HttpException
    • Forbidden Request
    • Internal Server Error
    • Unauthorized Exception
    • Check for “Bad Request” and throw IncorrectLoginPasswordException
    • ConnectionException – No Internet
    • Any other error is just NetworkException
  3. While APIs response format is not expected. eg, JsonSyntaxException BEGIN_OBJECT but was BEGIN_ARRAY, Expected BEGIN_OBJECT but was STRING

1. NullPointerException

NullPointerException is most common exception occurs when you performing operation of null object. Let’s suppose our app has a screen containing RecyclerView that showing feed data from a model class. The model class is simple POJO that containing the following attributes described by the API.

public class Row {

    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("description")
    @Expose
    private String description;
    @SerializedName("imageHref")
    @Expose
    private String imageHref;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getImageHref() {
        return imageHref;
    }

    public void setImageHref(String imageHref) {
        this.imageHref = imageHref;
    }
}

On the screen, we have decided to show the title with uppercase letters. like below

TextView titleView = (TextView) findViewById(R.id.tvTitle);
titleView.setText(row.getTitle().toUpperCase());

Problem Statement

The app now is working fine as expected, you submitted at Google Play and user are happy to use it. Now let’s suppose APIs stop the sending title parameter. then what happens.? The app will crash when trying to show the title because we are applying toUpperCase () method on null object.

Proposed Solution

The proposed solution validates the model before it’s sent to the view, and somehow validation failed, show the error message to the user. But runtime just checking every property against null, not a good practice. It’s affected your app performance. then how to do .?

We need to find out the way so we tell compiler at runtime which properties we want to be verified. We can do using annotations.

Annotations, a form of metadata, provide data about a program that is not part of the program itself.

Create model validator script

Go to src and create a file with IsDefined name

package com.androidwave.utils;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created on : Jan 13, 2019
 * Author     : Morris
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface IsDefined {
}

In this class, we are using two annotations

  • Target(ElementType.FIELD) – That means the IsDefined annotation should be available at runtime
  • Retention(RetentionPolicy.RUNTIME) – It means the IsDefined will annotate class attributes.

Create a POJO validator class

Let’s create a POJO validator class that will receive a model object, search each attribute that annotated by IsDefined and if it has null value will throw an exception.

package com.androidwave.utils;

import android.support.annotation.NonNull;

import java.lang.reflect.Field;

/**
 * Created on : Jan 13, 2019
 * Author     : Morris
 */
public class PojoValidator {
    private Object model;

    public PojoValidator(@NonNull Object model)  {
        this.model = model;
    }

    public void validate() throws IllegalArgumentException {

        if (model == null) {
            throw new IllegalArgumentException("Model cannot be null");
        }

        final Field[] modelFields = model.getClass().getDeclaredFields();

        for (Field modelField : modelFields) {
            validateIsDefinedField(modelField);
        }
    }

    private void validateIsDefinedField(Field field) {

        if (field.isAnnotationPresent(IsDefined.class)) {

            Object attributeValue = null;
            field.setAccessible(true);

            try {
                attributeValue = field.get(model);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

            if (attributeValue == null) {
                throw new IllegalArgumentException(field + " is required");
            }

        }
    }
}

2. Manage HttpException

 subscription.add(
                service.getFeedResponse()
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .doOnTerminate(() -> {
                            if (view != null) {
                                view.onFetchDataCompleted();
                            }
                        })
                        .subscribe(feedResponse -> {
                            if (view != null) {
                                /**
                                 * Update view here
                                 */
                                view.onFetchDataSuccess(feedResponse);
                            }
                        }, error -> {
                           handleApiError(error);
                        })
        );
Definition of handle API error
 public void handleApiError(Throwable error) {
        if (error instanceof HttpException) {
            switch (((HttpException) error).code()) {
                case HttpsURLConnection.HTTP_UNAUTHORIZED:
                    mView.onError("Unauthorised User ");
                    break;
                case HttpsURLConnection.HTTP_FORBIDDEN:
                    mView.onError("Forbidden");
                    break;
                case HttpsURLConnection.HTTP_INTERNAL_ERROR:
                    mView.onError("Internal Server Error");
                    break;
                case HttpsURLConnection.HTTP_BAD_REQUEST:
                    mView.onError("Bad Request");
                    break;
                case API_STATUS_CODE_LOCAL_ERROR:
                    mView.onError("No Internet Connection");
                    break;
                default:
                    mView.onError(error.getLocalizedMessage());

            }
        }
    }

3. The APIs response format is not expected

This problem mostly occurs during development going on, So I have written a separate article with complete source code, Read here Retrofit Globally Error Handling 🙂

Понравилась статья? Поделить с друзьями:
  • Retrofit error handling
  • Retroarch как изменить язык
  • Retrieving info самп как исправить
  • Retracker local error
  • Retail 01 горит error