package com.ycwl.basic.exception; import com.ycwl.basic.enums.BizCodeEnum; import com.ycwl.basic.notify.NotifyFactory; import com.ycwl.basic.notify.entity.NotifyContent; import com.ycwl.basic.utils.ApiResponse; import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.Enumeration; import java.util.stream.Collectors; /** * @date 2022年09月23日 10:19 * 全局异常处理器 */ @RestControllerAdvice(basePackages = {"com.ycwl.basic"}) public class CustomExceptionHandle { private static final Logger LOGGER = LoggerFactory.getLogger(CustomExceptionHandle.class); @ExceptionHandler(CheckTokenException.class) public ApiResponse tokenExceptionHandler(HttpServletResponse response, BaseException ex) { response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); return ApiResponse.buildResponse(200, ex.getMessage()); } @ExceptionHandler(MissTokenException.class) public ApiResponse tokenMissExceptionHandler(HttpServletResponse response, BaseException ex) { response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); return ApiResponse.buildResponse(ex.getStatus(), ex.getMessage()); } @ExceptionHandler(TokenExpireException.class) public ApiResponse tokenExpireException(HttpServletResponse response, BaseException ex) { response.setStatus(HttpStatus.OK.value()); return ApiResponse.buildResponse(ex.getStatus(), ex.getMessage()); } @ExceptionHandler(BaseException.class) public ApiResponse baseExceptionHandler(HttpServletResponse response, BaseException ex) { response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); return ApiResponse.buildResponse(ex.getStatus(), ex.getMessage()); } /** * 自定义异常统一处理类 */ @ExceptionHandler(value = BizException.class) public ApiResponse handle(BizException bizException) { return ApiResponse.buildResponse(bizException.getCode(), bizException.getMsg()); } /** * 异常统一返回处理 */ @ExceptionHandler(value = Exception.class) public ApiResponse handle(Exception e) { LOGGER.error("系统异常 -> {}", e.getMessage(), e); new Thread(() -> { NotifyFactory.to().sendTo( new NotifyContent( "帧途后台报错了!", e.getMessage() + "\n---\n请求主体:\n```\n" + getRequestAsText() + "\n```\n---\n错误栈:\n```\n" + getStackTrace(e) + "\n```" ), "default_user" ); }).start(); return ApiResponse.buildResult(BizCodeEnum.SERVER_UNKONWN_ERROR); } public String getStackTrace(Throwable e) { StringBuilder sb = new StringBuilder(); StackTraceElement[] stackTrace = e.getStackTrace(); sb.append(e.getClass().getName()).append(": ").append(e.getMessage()).append("\r\n"); for (StackTraceElement stackTraceElement : stackTrace) { sb.append("\tat ").append(stackTraceElement.toString()).append("\r\n"); } return sb.toString(); } public String getRequestAsText() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes == null) { return "---"; } HttpServletRequest request = attributes.getRequest(); StringBuilder rawReq = new StringBuilder(); rawReq.append(request.getMethod()).append(" ").append(request.getRequestURL()); String queryString = request.getQueryString(); if (queryString != null) { rawReq.append("?").append(queryString); } rawReq.append("\r\n"); Enumeration headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); rawReq.append(headerName).append(": ").append(request.getHeader(headerName)).append("\r\n"); } rawReq.append("\r\n"); // 获取body try { rawReq.append(request.getReader().lines().collect(Collectors.joining("\r\n"))); rawReq.append("\r\n"); } catch (IOException ignored) { } return rawReq.toString(); } /** * 移动端自定义异常统一处理类 */ @ExceptionHandler(value = AppException.class) public ApiResponse handle(AppException appException) { return ApiResponse.buildResponse(appException.getCode(), appException.getMsg()); } /** * 移动端自定义异常统一处理类 */ @ExceptionHandler(value = HttpMessageNotReadableException.class) public ApiResponse handle(HttpMessageNotReadableException httpMessageNotReadableException) { return ApiResponse.buildResponse(500, "请求参数格式错误"); } /** * 文件上传超长异常统一处理 */ @ExceptionHandler(value = SizeLimitExceededException.class) public ApiResponse handle(SizeLimitExceededException sizeLimitExceededException) { return ApiResponse.buildResponse(415, "文件过大,请重新上传"); } }