【问题标题】:How do I handle response errors using with Retrofit and RxJava/RxAndroid?如何使用 Retrofit 和 RxJava/RxAndroid 处理响应错误?
【发布时间】:2023-03-15 00:51:01
【问题描述】:

我无法确定如何使用改造和 RxAndroid 处理响应错误。如果出现网络错误或类似情况,则会调用 onError(),但我需要能够获得响应以检查是否存在身份验证错误。相反,我得到的是一个带有空字符串的令牌,我不知道为什么。解决此问题的最佳方法是什么?

这是我目前的 RxAndroid 通话。

    Client.getInstance().getService()
            .getToken(usernameET.getText().toString(), passwordET.getText().toString())
            .subscribe(new Subscriber<SiteInfo>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {
                    e.printStackTrace();
                }

                @Override
                public void onNext(SiteInfo siteInfo) {
                    Log.d(TAG, "onNext "+ token.toString());
                }
            });

这是我的改装服务

@GET("my_url_here")
Observable<Token> getToken(
        @Query("username") String username,
        @Query("password") String password
);

这是我当前的适配器

RestAdapter restAdapter = new RestAdapter.Builder()
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .setEndpoint(BASE_URL)
            .build();

service = restAdapter.create(MyService.class);

这是我的令牌类。

public class Token {
    private String token;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    @Override
    public String toString() {
        return token;
    }
}

我应该如何处理这个问题。可以在 RxAndroid 部分完成,还是我需要向我的 RestClient 添加一些东西,或者完全是其他东西?

谢谢。

编辑

07-01 06:38:04.562    1680-1793/uk.co.dyolo.thing D/Retrofit﹕ ---> HTTP GET my_website_here
07-01 06:38:04.562    1680-1793/uk.co.dyolo.thing D/Retrofit﹕ ---> END HTTP (no body)
07-01 06:38:04.610    1680-1793/uk.co.dyolo.thing D/Retrofit﹕ <--- HTTP 200 my_website_here (48ms)
07-01 06:38:04.610    1680-1793/uk.co.dyolo.thing D/Retrofit﹕ : HTTP/1.1 200 OK

【问题讨论】:

  • 什么是authentication error?如果状态不是 200,则 Retrofit 的 observable 会发出错误。
  • 不幸的是,服务器没有给出状态码。 {"error":"The username was not found in the database","stacktrace":null,"debuginfo":null,"reproductionlink":null} 是我得到的回复。
  • 服务器为您提供状态。状态码是http 的一部分。
  • 啊,是的,我明白你的意思。那么服务器必须给我一个200 代码,这不是很有帮助。
  • 我认为他是在暗示服务器向他发送 200。但响应包含错误字符串。在那种情况下,你真的不能为此责怪改造。要求模块所有者发送错误代码作为响应,例如 500 等,或者通过解析 JSON 并检查是否 error!=null 自行处理。

标签: java android retrofit rx-java rx-android


【解决方案1】:

我找到了解决办法

首先,我将我的 Token 对象扩展为具有错误属性。

public class Token {

    private String token;
    private String error;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    @Override
    public String toString() {
        return token;
    }
}

然后我在我的 RxJava 链中添加了一个运算符,它可以检查错误字段是否不是 null。如果有错误,抛出一个自定义异常,调用订阅者onError 允许我处理它。

if (token.getError() != null) {
    throw OnErrorThrowable.from(new UserAuthenticationException(token.getError()));
    }

如果有错误,抛出一个自定义异常,调用订阅者onError 允许我处理它。

if (e instanceof OnErrorThrowable){
    if (e.getCause() instanceof UserAuthenticationException){
        Log.d(TAG, "onError "+e.getCause().getMessage());
    }
    e.getCause().printStackTrace();
}

【讨论】:

  • 你能告诉我们你在 RxJava 链中添加的运算符是什么吗?)我做的事情和你一样,我想在某处分解错误检查。我目前正在使用.flatMap(...),它不是那么“漂亮”。
  • @mithrop 我相信我只是使用了地图运算符,如果有错误,我会抛出异常,否则,我只是返回了对象。所以在这种情况下,map.
【解决方案2】:

这有点晚了,但是如果有人在这里徘徊,只要从服务器返回的请求带有 [200,300) 间隔之外的错误代码,Retrofit 2 就会将 HttpException 的实例传递给 onError 回调...

throwable -> {
    if(throwable instanceof HttpException){
        switch(((HttpException)throwable).code()){
            // your error handling logic 
        }
    }
}

您还可以从此对象中检索整个响应..

【讨论】:

    猜你喜欢
    • 2015-11-21
    • 2017-01-01
    • 1970-01-01
    • 2017-11-24
    • 2020-01-02
    • 2021-05-11
    • 2016-06-17
    • 2016-02-17
    • 1970-01-01
    相关资源
    最近更新 更多