java异常和错误码定义规范及其使用

时间:2019-07-29 18:57:33   收藏:0   阅读:1892

前言

 

场景

 

以前可能遇到的问题

 

问题分析

 

对异常进行分类

 

正确对待第三方工具(依赖)抛出的异常

 

用有限的异常类处理义务中复杂多变的无限可能

  这个问题,其实大家都在使用,那就是配合错误码使用。和定义异常类一样的到了,定义和使用错误码的时候也要将其归类定义,避免重复定义和混乱使用。而且到最后你一定会发现,所定义的错误码大部分是业务错误码居多,即该错误码明确代表了一个错误码描述,而这个错误描述是给调用方看的,而系统级别的异常详细信息已经堆栈形式在日志中打印出来了,那不同的错再多定义一个错误码也意义不大。当然,如果要通过错误码对异常分类进行统计的情况除外,但是如果一个系统已经到了这个地步的话基本可以选择其他方案了。

 

异常类和错误码定义示例

需求

 

示例代码

技术图片
public interface ErrorCode {
  String getErrorCode();
  String getErrorDesc();
}
获取错误码及其藐视信息接口定义
技术图片
/**
 * 用户异常错误码枚举
 */
public enum UserErrorCode implements ErrorCode {
  /**
   * 用户名错误
   */
  USERNAME_ERR("username-err", "用户名错误"),
  /**
   * 密码错误
   */
  PASSWORD_ERR("PASSWORD-ERR", "密码错误"),
  ;

  UserErrorCode(String errorCode, String errorDesc) {
    this.errorCode = errorCode;
    this.errorDesc = errorDesc;
  }

  // 错误码.
  @Getter
  private String errorCode;
  // 错误码对应的外部描述信息.
  @Getter
  private String errorDesc;
}
用户异常错误码枚举示例
技术图片
/**
 * 系统异常错误码枚举
 */
public enum SystemErrorCode implements ErrorCode {
  /**
   * 系统内部错误
   */
  SYSTEM_ERR("system-err", "系统内部错误"),
  ;

  SystemErrorCode(String errorCode, String errorDesc) {
    this.errorCode = errorCode;
    this.errorDesc = errorDesc;
  }

  @Getter
  private String errorCode;
  @Getter
  private String errorDesc;
}
系统异常错误码枚举示例

技术图片
import lombok.Getter;

public class UserException extends RuntimeException implements ErrorCode {

  @Getter
  private String errorCode;
  @Getter
  private String errorDesc;

  /**
   * @param errorCode 枚举的错误码类型,其中包含了错误码和对应的错误码描述信息.
   */
  public UserException(UserErrorCode errorCode) {
    super();
    this.errorCode = errorCode.getErrorCode();
    this.errorDesc = errorCode.getErrorDesc();
  }

  /**
   * @param errorCode 枚举的错误码类型,其中包含了错误码和对应的错误码描述信息.
   * @param message   最好是自定义的详细描述信息,用于打日志,也可以和{@link ErrorCode#getErrorDesc()}相同
   */
  public UserException(UserErrorCode errorCode, String message) {
    super(message);
    this.errorCode = errorCode.getErrorCode();
    this.errorDesc = errorCode.getErrorDesc();
  }

  /**
   * @param errorCode 枚举的错误码类型,其中包含了错误码和对应的错误码描述信息.
   * @param cause     嵌套的错误堆栈
   */
  public UserException(UserErrorCode errorCode, Throwable cause) {
    super(cause);
    this.errorCode = errorCode.getErrorCode();
    this.errorDesc = errorCode.getErrorDesc();
  }

  /**
   * @param errorCode 枚举的错误码类型,其中包含了错误码和对应的错误码描述信息.
   * @param message   最好是自定义的详细描述信息,用于打日志,也可以和{@link ErrorCode#getErrorDesc()}相同
   * @param cause     嵌套的错误堆栈
   */
  public UserException(UserErrorCode errorCode, String message, Throwable cause) {
    super(message, cause);
    this.errorCode = errorCode.getErrorCode();
    this.errorDesc = errorCode.getErrorDesc();
  }
}
包含各种构造方法的自定义异常

ps: 如果你看懂了这个异常类的构造方法定义的话,那你一定知道为什么错误码定义要用枚举了,因为只要不是字符串就行,否则会和官方默认的冲突,官方的默认字符串表示该错的描述性信息,而我们的不仅要利用描述信息同时能在堆栈中打印的特性,还需要将我们错误码和错误码描述信息传入(这里的描述信息一般是传到到调用方的,不是用来打日志的,所以这两处的描述一般是不相同的),一次传入多个信息,所以对象是我们最好的选择。

 

如有不足之处欢迎留言交流。

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!