使用场景
异常兜底方案,及时捕获发生的异常并作出相应的处理,避免将问题抛到服务端然后造成服务出问题的情况
异常体系
在代码中使用(搭配已经定义好的全局异常码一起使用)
1️⃣在src/main/java/.../common/convention/exception路径下新建异常体系相关的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| /** * 抽象项目中三类异常体系,客户端异常、服务端异常以及远程服务调用异常 * * @see ClientException * @see ServiceException * @see RemoteException */ @Getter public abstract class AbstractException extends RuntimeException {
public final String errorCode;
public final String errorMessage;
public AbstractException(String message, Throwable throwable, IErrorCode errorCode) { super(message, throwable); this.errorCode = errorCode.code(); this.errorMessage = Optional.ofNullable(StringUtils.hasLength(message) ? message : null).orElse(errorCode.message()); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| /** * 客户端异常 */ public class ClientException extends AbstractException {
public ClientException(IErrorCode errorCode) { this(null, null, errorCode); }
public ClientException(String message) { this(message, null, BaseErrorCode.CLIENT_ERROR); }
public ClientException(String message, IErrorCode errorCode) { this(message, null, errorCode); }
public ClientException(String message, Throwable throwable, IErrorCode errorCode) { super(message, throwable, errorCode); }
@Override public String toString() { return "ClientException{" + "code='" + errorCode + "'," + "message='" + errorMessage + "'" + '}'; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| /** * 远程服务调用异常 */ public class RemoteException extends AbstractException {
public RemoteException(String message) { this(message, null, BaseErrorCode.REMOTE_ERROR); }
public RemoteException(String message, IErrorCode errorCode) { this(message, null, errorCode); }
public RemoteException(String message, Throwable throwable, IErrorCode errorCode) { super(message, throwable, errorCode); }
@Override public String toString() { return "RemoteException{" + "code='" + errorCode + "'," + "message='" + errorMessage + "'" + '}'; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| /** * 服务端异常 */ public class ServiceException extends AbstractException {
public ServiceException(String message) { this(message, null, BaseErrorCode.SERVICE_ERROR); }
public ServiceException(IErrorCode errorCode) { this(null, errorCode); }
public ServiceException(String message, IErrorCode errorCode) { this(message, null, errorCode); }
public ServiceException(String message, Throwable throwable, IErrorCode errorCode) { super(Optional.ofNullable(message).orElse(errorCode.message()), throwable, errorCode); }
@Override public String toString() { return "ServiceException{" + "code='" + errorCode + "'," + "message='" + errorMessage + "'" + '}'; } }
|
2️⃣在src/main/java/…/common/web路径下新建全局异常拦截器类GlobalExceptionHandler,同时为项目引入Hutool依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| /** * 全局异常处理器 * */ @Component @Slf4j @RestControllerAdvice public class GlobalExceptionHandler {
/** * 拦截参数验证异常 */ @SneakyThrows @ExceptionHandler(value = MethodArgumentNotValidException.class) public Result validExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException ex) { BindingResult bindingResult = ex.getBindingResult(); FieldError firstFieldError = CollectionUtil.getFirst(bindingResult.getFieldErrors()); String exceptionStr = Optional.ofNullable(firstFieldError) .map(FieldError::getDefaultMessage) .orElse(StrUtil.EMPTY); log.error("[{}] {} [ex] {}", request.getMethod(), getUrl(request), exceptionStr); return Results.failure(BaseErrorCode.CLIENT_ERROR.code(), exceptionStr); }
/** * 拦截应用内抛出的异常 */ @ExceptionHandler(value = {AbstractException.class}) public Result abstractException(HttpServletRequest request, AbstractException ex) { if (ex.getCause() != null) { log.error("[{}] {} [ex] {}", request.getMethod(), request.getRequestURL().toString(), ex.toString(), ex.getCause()); return Results.failure(ex); } log.error("[{}] {} [ex] {}", request.getMethod(), request.getRequestURL().toString(), ex.toString()); return Results.failure(ex); }
/** * 拦截未捕获异常 */ @ExceptionHandler(value = Throwable.class) public Result defaultErrorHandler(HttpServletRequest request, Throwable throwable) { log.error("[{}] {} ", request.getMethod(), getUrl(request), throwable); return Results.failure(); }
private String getUrl(HttpServletRequest request) { if (StringUtils.isEmpty(request.getQueryString())) { return request.getRequestURL().toString(); } return request.getRequestURL().toString() + "?" + request.getQueryString(); } }
|
3️⃣在代码中使用
🔥在service的实现类中使用
1
| throw new ClientException(UserErrorCodeEnum.USER_NULL);
|