【问题标题】:Best practice for handling HTTP error call处理 HTTP 错误调用的最佳实践
【发布时间】:2011-08-13 04:58:43
【问题描述】:

我将这个问题发布到了 Android 开发者小组,但我想在这里发布给其他可能像我一样面临设计问题的人:

我一直在寻找有关如何处理 HTTP 错误的习语或范例。

基本上,

我有一个在后台线程中运行的 AsyncTask,它调用我的一个名为 executeRequest() 的静态方法。

这一切都在 doInBackground() 部分完成。 executeRequest() 会抛出两种类型的异常。所有通信错误的 IOException 和我自己的异常的 ServerErrorResponse 异常。例如,如果客户端向服务器发送了错误的信息,整个 HTTP 工作但服务器抱怨(可能我传递了无效的参数或 id),就会发生这种情况。

所以,我所做的就是将结果包装在我自己的“结果对象”中。

在 onPostExecute() 中,我检查结果是否失败,然后尝试在 UI 线程中处理它。但是,我现在必须开始做

Exception e = result.getException();
if (e != null) {
  if (e instanceof IOException) { //network error
   //handle network error here
 } else if (e instanceof ServerErrorResponseException) {
   //handle server error response here
}

正如你所看到的,这变得很烦人,对于每一个新的异常,我都必须使用 instanceof 来检查它。有没有办法解决它或我可以遵循的设计来避免这种情况?我希望在 UI 线程中处理异常,以防我向用户显示对话框或其他内容。

有什么想法吗?

【问题讨论】:

    标签: java android multithreading http exception


    【解决方案1】:
    Exception e = result.getException();
    if (e != null) {
      try {
        throw e;
      } catch (IOException ex) {
        //handle network error here
      } catch (ServerErrorResponseException ex) {
        //handle server error response here
      } catch (Exception ex) {
        //handle RuntimeException and others here
        //(You weren't just going to ignore them, were you?)
      }
    }
    

    【讨论】:

    • 您还可以查看java.util.concurrent 包的ExecutorService。它使处理来自后台任务的异常变得非常简单;如果一个任务抛出一个Exception,试图get() 来自关联的Future 的结果会抛出一个异常而不是得到结果。因此,您的应用程序不必进行明确的“是否有错误”检查。
    • 是的 Androids AsyncTask 使用和 ExecutorService 。让我回顾一些东西,我会将此回复标记为答案。除了重新投掷和正确接住,你能想到的没有其他方法了?
    • 这不是唯一的方法(使用instanceof 进行测试也可以),但我认为这是最好的方法。这是一种常见模式,在其他 API 中(间接)使用。
    【解决方案2】:

    这只是几个选项中的一个:

    创建一个类似的接口

    public interface ResultReceiver {
      public void onSuccess(YourClass object);
      public void onError(Exception err);
      //alternatives to the former:
      public void onNetworkError(IOException err); //maybe the parameter is optional?
      public void onServerProblem(ServerErrorResponseException err);
    }
    

    现在,在您的 onPostExecute 中执行类似的操作

    result.handleWith(this); //I'm assuming your activity implements ``ResultReceiver`` interface
    

    如果您愿意,可以在 Activity 之外创建结果处理程序(此选项更好,以避免跨 Activity 的代码重复)

    最后,handleWith 实现:

    public void handleWith(ResultReceiver handler){ 
      Exception e = result.getException();
      if (e != null) {
        if (e instanceof IOException) { //network error
         handler.onNetworkError(e);
       } else if (e instanceof ServerErrorResponseException) {
         handler.onServerProblem(e);
      } else {
         handler.onSuccess(this);
      }
    
    }
    

    【讨论】:

    • 佩德罗,感谢您的回复,但这不是我想要的。我一直在寻找通过使用 instanceof 来避免检查错误类型的模式。如果出现新类型的异常,我必须添加另一个 elseif 语句并更新接口。
    • 通常情况下,我有 3 或 4 种情况:Success、NetworkError、ServerError 以及可能是意外错误。通常我会分别处理这 3 个(或 4 个)案例。进一步的错误应该属于这些选项之一,在这些情况下,我会发送一些字符串或代码,以提供有关应显示哪些消息的信息。如果你能做到这一点,你就不必创建其他类型的错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 2017-11-26
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    相关资源
    最近更新 更多