【问题标题】:How to handle different types of exceptions and errors in retrofit 2.0.1如何在改造 2.0.1 中处理不同类型的异常和错误
【发布时间】:2017-01-10 15:11:04
【问题描述】:

我正在使用 Retrofit 2.0.1。我想处理所有类型的网络错误和异常(比如没有网络连接、超时错误、找不到服务器等)我找到了这个link。但有些方法在 v1.8.0 中已弃用。如何在 2.0.1 中做到这一点?

【问题讨论】:

    标签: android rest httpresponse retrofit2


    【解决方案1】:

    如果您需要 centeralize 错误处理程序,请查看 this 线程但是如果您只需要一个简单的错误处理程序,您可以这样做:

     @Override
     public void onFailure(Throwable throwable) {
        if (throwable instanceof HttpException) {
           // We had non-2XX http error
        }
        if (throwable instanceof IOException) {
           // A network or conversion error happened
        }
    
        // We don't know what happened. We need to simply convert to an unknown error
        // ...
      }
    

    【讨论】:

    • 感谢@Amir 的回复,我看到了你的链接。但是当出现网络连接问题时,进入 onFailure 并返回 UnKnownHostException。我想通过消息向用户发送问题的确切具体原因?可以通过这个来解决吗?
    • 这取决于你想要处理什么样的错误。例如在上面的代码中,您可以检测哪种类型的网络断开连接(Wifi | 移动)或在 HttpException 中您可以解析 500,400,401,404,....
    • 嗨阿米尔,我想给你一个测试用例,然后你就可以理解了。当我的网络禁用并点击进入故障块的 api 并给出 UnKnownHostException 而不是 HttpException 。所以,在那个时候它没有返回任何代码。那么如何处理它?
    • @Suman 服务器不返回任何状态码?改造 response.code() 通常会返回正确的代码,看看可能会解决您的问题。
    • 感谢@Amir 的支持,我可以解决它。UnknownHoStException 不是 HttpError。需要像 if (throwable instanceof UnknownHostException) {} 一样处理。
    【解决方案2】:

    无论如何都应该检查连接状态,与RetroFit无关,查找ConnectivityManager

    (快速解决方案是 这个,根据您的需要进行修改):

    public boolean isConnected()
    {
      ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
      NetworkInfo info = manager.getActiveNetworkInfo();
    
      return (info != null && info.isConnected());
    }
    

    编辑: 考虑一下 - ConnectivityManager 让你知道你有一个用于传出数据的接口,如果你想知道你是否真的有一个外部链接,我建议你 ping 你的服务器(或任何其他会响应的已知域),如果ping 很好,你有一行,TimeoutsserverNotFound - 使用你在 onFailure() 中返回的 http 代码进行 api 请求(例如 404、400、200 等)。

    原因

    ping 只是一个 udp 数据包,它让您知道服务器在那里并且还活着,因此 ping 有效但 http 请求将返回 Bad Request 的情况是非常可能的,并且可以轻松处理,逻辑取决于你。

    对于其他内容 - 实现所需处理所需的所有信息都可以在回调中找到。

    此示例使用ResponseBody,您可以从标头中获取交货信息:

    @Override
    public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> rawResponse)
    {
      try
      {
       String response = rawResponse.headers().toString();
       //now print this...
      }
      catch(Exception e)
      {
       e.printStackTrace();
      }
    }
    

    Timeouts 和 serverNotFound 可以通过 onFailure 回调来处理(这是框架,在里面实现你需要的东西,阅读它):

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable throwable)
    {
     //use throwable.get.... to know what happened
     throwable.printStackTrace();
    }
    

    希望这对您有任何帮助

    【讨论】:

    • 感谢您的回复,ConnectivityManager 仅检查 wifi 是否启用和数据是否启用,在检查此并点击 api 后,但在这种情况下数据不可用,它会转到 OnFailure 块。在这种情况下,我想处理连接错误和服务器错误..有什么方法可以处理这个?我想通过消息显示所有错误和问题用户
    • 编辑了答案,看看,记住你必须自己去捕捉和理解回复。
    猜你喜欢
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 2014-03-19
    • 2011-10-19
    • 2015-06-12
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多