改善异常处理的6条提示

25 篇文章 0 订阅

正确处理异常可以为你节省数小时(甚至数天)的故障排除时间。意外的生产问题可能会破坏你的晚餐和周末计划。如果不尽快解决,它们甚至会影响你的声誉。制定明确的异常管理政策将节省你诊断,重现和纠正问题的时间。这里有6条技巧可以改善你的异常处理。

抽丝剥茧 细说架构那些事——【优锐课】 欢迎加入Java学习资料交流qq群:907135806与我们一起探讨。

1.使用单个系统范围的异常类

不必为每种异常类型创建单独的类,而只需创建一个。 并使其扩展RuntimeException。 这将减少你的课程数量,并且无需声明无论如何都不会处理的异常。

我知道你在想什么:如果异常类型相同,我该如何区分? 以及如何跟踪特定于类型的属性? 继续阅读!

2.对错误代码使用枚举

我们大多数人都受过训练,可以将异常原因放入其信息中。查看日志文件(ugh)时很好,但是确实有缺点:
1.邮件无法翻译(除非你是Google)。
2.邮件无法轻松地映射为用户友好的文本。
3.无法通过程序检查邮件。

在消息中放入信息也会使每个开发人员措辞受限,这可能导致同一失败的不同短语。

更好的方法是使用枚举来指示异常的类型。 为每种错误类别(付款,身份验证等)创建一个枚举。 使枚举实现一个ErrorCode接口,并将其作为异常中的字段引用。引发异常时,只需传入适当的枚举即可。

	throw new SystemException(PaymentCode.CREDIT_CARD_EXPIRED);

现在,当你需要测试特定案例时,只需将异常的代码与枚举进行比较即可。

	} catch (SystemException e) {
 if (e.getErrorCode() == PaymentCode.CREDIT_CARD_EXPIRED) {
  ...
   }
	}

现在,可以使用错误代码作为资源包的查找关键字来检索用户友好的国际化文本。

public class SystemExceptionExample3 {

    public static void main(String[] args) {
        System.out.println(getUserText(ValidationCode.VALUE_TOO_SHORT));
    }

    public static String getUserText(ErrorCode errorCode) {
            if (errorCode == null) {
           return null;
       }
              String key = errorCode.getClass().getSimpleName() + "__" + errorCode;
       ResourceBundle bundle = 
ResourceBundle.getBundle("com.northconcepts.exception.example.exceptions");
       return bundle.getString(key);
  }

}

3.将错误编号添加到枚举

在某些情况下,数字错误代码可以与每个异常关联。例如,HTTP响应。对于这些情况,请将getNumber方法添加到ErrorCode接口并在每个枚举中实现。

public enum PaymentCode implements ErrorCode {
  SERVICE_TIMEOUT(101),
  CREDIT_CARD_EXPIRED(102),
  AMOUNT_TOO_HIGH(103),
  INSUFFICIENT_FUNDS(104);
 
  private final int number;
 
  private PaymentCode(int number) {
    this.number = number;
  }
 
  @Override
  public int getNumber() {
    return number;
  }
 
}

编号可以在所有枚举中全局唯一,也可以由每个枚举自行编号。你甚至可以使用隐式ordinal()方法或从文件或数据库中加载数字。

4.将动态字段添加到你的例外中

良好的异常处理意味着还记录相关数据,而不仅仅是堆栈跟踪。这样可以在诊断和重现错误时节省大量时间。当你的应用停止运行时,客户不必告诉你他们在做什么(你已经知道并希望对其进行修复)。

最简单的方法是将java.util.Map字段添加到异常中。新字段的工作是按名称保存你所有与异常相关的数据。你还需要按照流畅的界面模式添加通用的setter方法。

现在,带有相关数据的抛出异常将类似于以下内容。

throw new SystemException(ValidationCode.VALUE_TOO_SHORT)
  .set("field", field)
  .set("value", value)
  .set("min-length", MIN_LENGTH);

5.防止不必要的嵌套

冗长的冗余堆栈跟踪没有人帮助。更糟的是,它们浪费了你的时间和资源。重新抛出异常时,请调用静态包装方法,而不是异常的构造函数。wrap方法将负责确定何时嵌套异常以及何时仅返回原始实例。

public static SystemException wrap(Throwable exception, ErrorCode errorCode) {
  if (exception instanceof SystemException) {
    SystemException se = (SystemException)exception;
    if (errorCode != null && errorCode != se.getErrorCode()) {
      return new SystemException(exception.getMessage(), exception, errorCode);
    }
    return se;
  } else {
    return new SystemException(exception.getMessage(), exception, errorCode);
  }
}
 
public static SystemException wrap(Throwable exception) {
  return wrap(exception, null);
}
用于重新抛出异常的新代码如下所示。
} catch (IOException e) {
  throw SystemException.wrap(e).set("fileName", fileName);
}

6.将中央记录器与Web仪表板一起使用

考虑这个技巧的奖金。根据你的情况,访问生产日志可能会很麻烦。可能涉及多个过渡的麻烦(因为许多开发人员无法访问生产环境)。

如果你在多服务器环境中,情况会变得更糟。找到合适的服务器-或确定问题仅影响一台服务器——可能很头疼。

我的建议是:
1.将日志汇总到一个位置,最好是一个数据库。
2.使该数据库可从Web浏览器访问。

有很多方法可以做到这一点,并且可能有产品可供选择:日志收集器,远程记录器,JMX代理,系统监视软件等。你甚至可以自己构建它。最主要的是你要尽快做。拥有之后,你将能够:
• 在几秒钟内解决问题。
• 为每个例外都提供一个URL,你可以在其中添加书签或电子邮件。
• 使你的支持人员能够确定根本原因而不涉及你。
• 防止测试人员针对同一错误创建多个故障单。另外,他们还将在票证中添加一个例外URL。
• 为你的业务省钱。
• 保持周末和声誉不变。

你有什么秘诀?

我希望你发现这些提示有用。通过在我的例外中提供正确的信息并将它们放在易于访问的位置,可以避免许多灾难和浪费的时间。如果你有一些自己的异常处理技巧,我想听听他们。

编码愉快!
另外近期整理了一套完整的java架构思维导图,分享给同样正在认真学习的每位朋友~
在这里插入图片描述
加入Java学习资料交流qq群:907135806和我们一起探讨吧!有想要JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java学习资料、视频课程和学习路线的童鞋也可以加vx:ddmsiqi 领取啦,共同进步~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值