当使用 Retrofit 2.0 Observables 时出现错误,如何获取响应体?

40
我正在使用Retrofit 2.0进行调用返回Observables的api。当调用成功且响应符合预期时,一切都很好。现在假设我们有一个错误响应,它会抛出onError。即使响应是错误的,我也想读取响应正文。
示例
@FormUrlEncoded
@POST("tokenLogin")
Observable<LoginResponse> loginWithToken(
        @Field("token") String pin
);

当请求和响应有效时,我得到正确的可观测对象,并且当出现错误时 onError 会按预期被调用。

正确的响应:

{ "status" : "authenticated" }
Observable 将其转换为正确的 Observable,我可以将响应作为 LoginResponse 对象读取。
现在,错误响应如下:
{ "errorMessage" : "You need to take some xyz action" }

我想读取错误响应并将消息显示给用户。我该如何做到这一点?

3个回答

59

只需检查throwable是否为HttpException实例,然后您就可以访问Retrofit响应

if (e instanceof HttpException) {
    ResponseBody body = ((HttpException) e).response().errorBody();
    ...
}

然后你可以使用转换器对其进行反序列化(或自己完成)。


21
您可以添加此代码块以显示错误消息。
@Override
public void onFailure(Throwable t) {

 if (t instanceof HttpException) {
        ResponseBody body = ((HttpException) t).response().errorBody();
        Gson gson = new Gson();
        TypeAdapter<ErrorParser> adapter = gson.getAdapter
                (ErrorParser
                        .class);
        try {
            ErrorParser errorParser =
                    adapter.fromJson(body.string());

            Logger.i(TAG, "Error:" + errorParser.getError());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1
我想了解一下你们的ErrorParser。谢谢 :) - Alston
@Alston ErrorParser 是 JSON 类。 - Akhila
@Akshay Shinde 谢谢兄弟,这对我很有帮助。做得好! - Bipin Bharti

5

Retrofit会返回一个Throwable对象,它是HttpException的一种类型。你需要做的第一步是了解错误体对象的结构。将展示如何在Kotlin中实现。一旦你知道了结构,你需要创建如下所示的Error.kt文件:

package com.test.test.qr.data.network.responsemodel
import com.google.gson.annotations.SerializedName

data class Error(
    @SerializedName("code")
    val code: String,
    @SerializedName("message")
    val message: String
)

现在你需要解析HttpException的正文内容到你创建的Error.Kt中。可以按照以下方式完成:
if(it is HttpException) {
    val body = it.response()?.errorBody()
    val gson = Gson()
    val adapter: TypeAdapter<Error> = gson.getAdapter(Error::class.java)
    try {
        val error: Error = adapter.fromJson(body?.string())
        Log.d("test", " code = " + error.code + " message = " + error.message)
    } catch (e: IOException) {
       Log.d("test", " Error in parsing")
    }
}

在Retrofit中,您在onError()方法中获取的是Throwable对象。希望对您有所帮助。祝编码愉快...:-)


1
运作如行星一般顺畅!! - Makari Kevin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接