处理一些运行时 HTTP 异常的好习惯是啥?

Posted

技术标签:

【中文标题】处理一些运行时 HTTP 异常的好习惯是啥?【英文标题】:What is a good practice of dealing with some runtime HTTP exceptions?处理一些运行时 HTTP 异常的好习惯是什么? 【发布时间】:2013-01-04 23:44:22 【问题描述】:

我有一个看起来像这样的小方法:

public static void unstarTrack(Context ctxContext, String strId) 

  try 

      HttpParams htpParameters = new BasicHttpParams();

      List<NameValuePair> lstCredentials = new ArrayList<NameValuePair>();
      lstCredentials.add(new BasicNameValuePair("t", String.valueOf(System.currentTimeMillis() / 1000)));
      lstCredentials.add(new BasicNameValuePair("__call", "favourites.removeSong"));

      HttpPost htpPost = new HttpPost(API_URL);
      htpPost.setEntity(new UrlEncodedFormEntity(lstCredentials));
      htpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:18.0) Gecko/20100101 Firefox/18.0");
      htpPost.addHeader("Accept-Encoding", "gzip");
      DefaultHttpClient dhcClient = new DefaultHttpClient(htpParameters);

      HttpResponse resResponse = dhcClient.execute(htpPost);
      Log.d(TAG, EntityUtils.toString(resResponse.getEntity()));

      return;

 catch (SocketException e) 
    throw new RuntimeException("problem with network connectivity.", e);
 catch (UnsupportedEncodingException e) 
    throw new RuntimeException("Encoding not supported.", e);
 catch (ClientProtocolException e) 
    throw new RuntimeException("A protocol exception was encountered.", e);
 catch (ParseException e) 
    throw new RuntimeException("An error occurred while trying to read the header elements.", e);
 catch (IOException e) 
    throw new RuntimeException("An error occurred while trying to read response stream.", e);

该方法本身非常简单,但它有一堆异常发生,我不知道应该如何处理这些异常。通过做一个简单的“e.printStackTrace()”来抑制它们似乎不是一个好主意,所以我开始阅读异常处理最佳实践,但我还是有点迷茫。我应该如何处理异常?

我需要对我的异常做点什么,因为我不想从方法中返回null。从我的方法返回 null 意味着调用方法将无法了解我的方法内部是否发生了异常。

我应该创建一个自定义异常并引发它还是应该简单地引发未经检查的异常?

调用方法对我的方法影响不大,即如果网络连接出现问题,可能会出现SocketException,如果读取流出现问题,可能会出现IOException。调用方法最多可以做的是稍后重试。

如果我重新抛出我捕获的所有异常,调用方法只会充满异常处理块。

(如果这似乎是一个微不足道的问题,我很抱歉。我只是想学习编写更好的代码。谢谢。)

【问题讨论】:

您正在为捕获的异常抛出异常;如果发生异常,您将不会返回 null,也不会返回任何内容。无论如何,你的方法被声明为void——你不能返回任何东西。 如何处理异常完全取决于...您希望如何处理异常。 只捕获对用户或您自己产生影响的异常。异常具有可在任何情况下使用的 getMessage() 方法,即使它已被 catch(Exception e) 捕获。还要决定如果发生任何这些异常会发生什么。应用程序应该终止吗?它应该显示一条消息吗?仅当您对某些异常提出不同的答案时才捕获专门的异常。 【参考方案1】:

创建一个具有适当抽象级别的专用异常(类似于 UnstarTrackException)。抛出这样的异常,包装你捕获的原始异常。这样,调用者只需处理一个异常(我假设所有异常都应该以相同的方式处理:重试)。

是否应检查此异常取决于您的喜好。如果要强制方法的所有调用者处理此异常,请将其设为已检查异常。如果您想让调用者选择他是否要处理此异常,请使用运行时异常。

如果此方法深埋在代码层中,并且只能在顶层处理异常,则运行时异常可能是更好的选择。事实上,除非您是该方法的唯一调用者,否则运行时异常也可能是更好的选择。如今,受检查的异常往往很少使用。

【讨论】:

"如今,已检查的异常往往很少使用。"真的吗?证据? Hibernate 从已检查异常变为所有未检查异常。 JDBC 使用检查异常,但 JPA 只使用运行时异常。 Spring 仅使用(几乎?)运行时异常。 Java 8 java.time API 只有运行时异常(如 DateTimeParseException),尽管旧的 SimpleDateFormat 类使用已检查的 ParseException。另见tutorials.jenkov.com/java-exception-handling/…

以上是关于处理一些运行时 HTTP 异常的好习惯是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Java Reactor 中嵌套 flatMaps 的好习惯是啥?

检查环境变量是不是存在的好习惯是啥?

从 API 接收 POST(推送通知)到 Laravel 应用程序的好习惯是啥?

在 Swift + SwiftUI 中处理错误的好习惯

这次项目中应该注意的问题和应该保持的好习惯

“通过引用”编辑对象的好习惯?