Как разобрать ошибку ответа на Throwable? - PullRequest
0 голосов
/ 06 февраля 2020

Я использую Retrofit и RxJava для отправки сетевых запросов следующим образом:

Как я объявляю запрос:

@POST("auth/profile/edit/")
fun updateProfile(@Body body: ProfileUpdateBody): Single<Response<Void>>

Как я звоню:

api.updateProfile(**some data**)
     .subscribeOn(Schedulers.io())
     .observeOn(AndroidSchedulers.mainThread())
     .doOnSubscribe {
          Log.d("----------", "Subscribed!")
     }
     .doOnSuccess {
          if(it.isSuccessful)
              Log.d("----------", "Success!")
          else
              Log.d("----------", "Not Successfull!")
     }
    .doOnError {
          Log.d("----------", "Error Happened!")
            }
    .subscribe({
     }, {

     })

Некоторый код удален для удобства чтения. Проблема в том, что, хотя я получаю ответы с 401 или 400 статусами, вызывается doOnSuccess. Разве doOnError не следует называть здесь? Я запутался.

В результате мой логакт показывает сообщение «Не успешно». Как убедиться, что doOnErro вызывается, когда я получаю ответы с 401 или 400 статусами?

Или я могу разобрать входящий ответ на Throwable и вызвать функцию doOnError()?

Ответы [ 3 ]

1 голос
/ 06 февраля 2020

Измените вызов API Retrofit так, чтобы он возвращал Completable:

@POST("auth/profile/edit/")
fun updateProfile(@Body body: ProfileUpdateBody): Completable

, затем обработайте «успешный случай» с помощью doOnComplete:

api.updateProfile(**some data**)
 .subscribeOn(Schedulers.io())
 .observeOn(AndroidSchedulers.mainThread())
 .doOnSubscribe {
      Log.d("----------", "Subscribed!")
 }
 .doOnComplete {
      Log.d("----------", "Success!")
 }
 .doOnError {
      Log.d("----------", "Error Happened!")
 }
 .subscribe({  }, {  })
1 голос
/ 06 февраля 2020

Реальный вопрос заключается в том, почему вы хотите выдать исключение при сбое запроса?

Здесь выполняются правильные процессы, doOnSuccess вызывается так, как задумано, потому что запрос возвратил ответ, не встретив исключение. Независимо от того, является ли ответ на запрос успешным или нет.

Вы должны соответствующим образом обработать состояние своего ответа и не выбрасывать произвольных исключений для него:

api.updateProfile(**some data**)
     .subscribeOn(Schedulers.io())
     .observeOn(AndroidSchedulers.mainThread())
     .subscribe(response -> {
         if (response.isSuccessful()) {
             // handle success
         } else {
             // handle failure
         }
     }, t -> {
         // handle thrown error
         yourErrorHandlerMethod(t);
     })
0 голосов
/ 06 февраля 2020

Ответ, который вы получаете, верен, ответ отображается в doOnSuccess, потому что API, по которому вы ударили, получен успешно, независимо от того, каким был код ответа. doOnError вызывается при сбое фактического API вызова, например, сбоя сети в середине или некоторых проблем на стороне сервера.

Или я могу проанализировать входящий ответ в Throwable и вызвать функцию doOnError ()?

Вы не можете сделать это вместо этого, вы можете обработать ответ в doOnSuccess как

 try {
 api.updateProfile(**some data**)
 .subscribeOn(Schedulers.io())
 .observeOn(AndroidSchedulers.mainThread())
 .doOnSubscribe {
      Log.d("----------", "Subscribed!")
 }
 .doOnSuccess {
      if(it.isSuccessful) // responce code = 200/201
          Log.d("----------", "Success!")
      else if (it.responseCode == 400 ){
          Log.d("----------", "Not Found!")
          // Call a method that handles this according to your requirement.
          PageNotFoundHandler();
          // OPTIONAL throw new UserException();
        }
      else if (it.responseCode == 401 ){
          Log.d("----------", "Not Authorised!")
          // Call a method that handles this according to your requirement.
          TokenExpiredHandler(); //OR
          UnAuthorizedAccessHandler();
          // OPTIONAL throw new UserException();
        }
      else {
          Log.d("----------", "Some another Error!")
          // Call a method that handles this according to your requirement.
          // OPTIONAL throw new UserException();
        }

 }
.doOnError {
      Log.d("----------", "Error Happened!")
        }
.subscribe({
 }, {

 })
 } catch 
 {
    ErrorHandler();
 }

Или я могу проанализировать входящий ответ в Throwable и вызвать функцию doOnError ()?

Поскольку вы упоминаете, что вы хотите бросать, вы можете достичь его с помощью блока try-catch.

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

...