需求
项目快要上线了,产品说测试环境的那些报错都给解决掉才能上线。我一下就纳闷了,什么报错,测试怎么没提bug呢?原来产品说的是各类的业务异常提示和系统错误提示。
项目里为了让用户体验,是不希望看见项目报错提示的,但是有时候一些设计是需要提醒用户错误操作或者提示环境因素的,还好我之前就设计了自定义异常
实现
定义好异常类型和对应展示效果,使用枚举定义错误码和提示内容
public final static String USER_NOT_FOUND = "用户名或密码错误";
public final static String USER_HAS_NO_ROLE = "未获得用户的角色信息";
自定义异常
public class ServiceException extends RuntimeException {
private static final long serialVersionUID = 2359767895161832954L;
private final IResultCode resultCode;
public ServiceException(String message) {
super(message);
this.resultCode = ResultCode.FAILURE;
}
public ServiceException(IResultCode resultCode) {
super(resultCode.getMessage());
this.resultCode = resultCode;
}
public ServiceException(IResultCode resultCode, Throwable cause) {
super(cause);
this.resultCode = resultCode;
}
public Throwable fillInStackTrace() {
return this;
}
public Throwable doFillInStackTrace() {
return super.fillInStackTrace();
}
public IResultCode getResultCode() {
return this.resultCode;
}
}
业务中对应已知异常抛出对应的提示,使用@RestControllerAdvice,捕获异常后统一返回封装好的格式。
异常分成两种:已知异常与未知异常,未知异常是着重需要关注的,所以会将未知异常结合日志系统入库。
- 以下为全局异常核心代码
@Slf4j
@Order
@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class })
@RestControllerAdvice
public class RestExceptionTranslator {
@ExceptionHandler(ServiceException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R handleError(ServiceException e) {
log.error("业务异常", e);
return R.fail(e.getResultCode(), e.getMessage());
}
@ExceptionHandler(SecureException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public R handleError(SecureException e) {
log.error("认证异常", e);
return R.fail(e.getResultCode(), e.getMessage());
}
@ExceptionHandler(Throwable.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public R handleError(Throwable e) {
log.error("服务器异常", e);
//发送服务异常事件
ErrorLogPublisher.publishEvent(e, UrlUtil.getPath(WebUtil.getRequest().getRequestURI()));
return R.fail(ResultCode.INTERNAL_SERVER_ERROR, (Func.isEmpty(e.getMessage()) ? ResultCode.INTERNAL_SERVER_ERROR.getMessage() : e.getMessage()));
}
}