增加seata异常拦截

This commit is contained in:
ajaxfan
2021-03-24 18:33:04 +08:00
parent 15de420589
commit dbfc63d7c8

View File

@ -34,13 +34,13 @@ import com.chinaunicom.mall.ebtp.common.util.JsonUtils;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.exceptions.ExceptionUtil; import cn.hutool.core.exceptions.ExceptionUtil;
import io.seata.core.context.RootContext; import io.seata.core.context.RootContext;
import io.seata.core.exception.RmTransactionException;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
/** /**
* 异常处理 * 异常处理 拦截BindException异常返回HttpStatus是400的绑定错误信息
* 拦截BindException异常返回HttpStatus是400的绑定错误信息
* 拦截FrameException异常返回HttpStatus是406的业务处理错误信息(支持自定义状态码) * 拦截FrameException异常返回HttpStatus是406的业务处理错误信息(支持自定义状态码)
* 拦截Exception异常返回HttpStatus是500服务器内部异常 * 拦截Exception异常返回HttpStatus是500服务器内部异常
* *
@ -53,238 +53,243 @@ import lombok.extern.slf4j.Slf4j;
@ConditionalOnProperty(name = "mconfig.exception-handle-enabled", matchIfMissing = true) @ConditionalOnProperty(name = "mconfig.exception-handle-enabled", matchIfMissing = true)
public class BusinessExceptionHandlerAdvice { public class BusinessExceptionHandlerAdvice {
/**
/** * 业务异常处理
* 业务异常处理 *
* * @param request 请求
* @param request 请求 * @param exception ServiceErrorException异常对象
* @param exception ServiceErrorException异常对象 * @return 响应
* @return 响应 */
*/ @ExceptionHandler(value = BusinessException.class)
@ExceptionHandler(value = BusinessException.class) @ResponseStatus(HttpStatus.OK)
@ResponseStatus(HttpStatus.OK) public BaseResponse<String> serviceErrorException(HttpServletRequest request, BusinessException exception) {
public BaseResponse<String> serviceErrorException(HttpServletRequest request, BusinessException exception) { // 堆栈信息转为字符串
//堆栈信息转为字符串 log.info(ExceptionUtil.stacktraceToString(exception));
log.info(ExceptionUtil.stacktraceToString(exception)); Map<String, Object> body = new HashMap<>();
Map<String, Object> body = new HashMap<>();
// body.put("path", request.getRequestURI()); // body.put("path", request.getRequestURI());
return BaseResponse.fail(exception.getCode(), exception.getMessage(), Convert.toStr(body)); return BaseResponse.fail(exception.getCode(), exception.getMessage(), Convert.toStr(body));
} }
/** /**
* hibernate valid 验证异常拦截 * hibernate valid 验证异常拦截
* *
* @param request 请求 * @param request 请求
* @param exception ServiceErrorException异常对象 * @param exception ServiceErrorException异常对象
* @return 响应 * @return 响应
*/ */
@ExceptionHandler(value = MethodArgumentNotValidException.class) @ExceptionHandler(value = MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleInvalidMethodArgException(HttpServletRequest request, MethodArgumentNotValidException exception) { public BaseResponse<String> handleInvalidMethodArgException(HttpServletRequest request,
//堆栈信息转为字符串 MethodArgumentNotValidException exception) {
log.info(ExceptionUtil.stacktraceToString(exception)); // 堆栈信息转为字符串
//按需重新封装需要返回的错误信息 log.info(ExceptionUtil.stacktraceToString(exception));
List<ArgumentInvalidResult> invalidArguments = new ArrayList<>(); // 按需重新封装需要返回的错误信息
//解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息 List<ArgumentInvalidResult> invalidArguments = new ArrayList<>();
BindingResult bindingResult = exception.getBindingResult(); // 解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息
for (FieldError error : bindingResult.getFieldErrors()) { BindingResult bindingResult = exception.getBindingResult();
ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult(); for (FieldError error : bindingResult.getFieldErrors()) {
invalidArgument.setDefaultMessage(error.getDefaultMessage()); ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult();
invalidArgument.setField(error.getField()); invalidArgument.setDefaultMessage(error.getDefaultMessage());
invalidArgument.setRejectedValue(error.getRejectedValue()); invalidArgument.setField(error.getField());
invalidArguments.add(invalidArgument); invalidArgument.setRejectedValue(error.getRejectedValue());
} invalidArguments.add(invalidArgument);
Map<String, Object> body = new HashMap<>(); }
body.put("errors", JsonUtils.objectToJson(invalidArguments)); Map<String, Object> body = new HashMap<>();
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase()); body.put("errors", JsonUtils.objectToJson(invalidArguments));
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
// body.put("path", request.getRequestURI()); // body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数验证错误", Convert.toStr(body)); return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数验证错误", Convert.toStr(body));
} }
/** /**
* 参数绑定异常 * 参数绑定异常
* *
* @param request 请求 * @param request 请求
* @param exception BindException异常对象 * @param exception BindException异常对象
* @return 响应 * @return 响应
*/ */
@ExceptionHandler(value = BindException.class) @ExceptionHandler(value = BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> methodArgumentNotValidHandler( public BaseResponse<String> methodArgumentNotValidHandler(HttpServletRequest request, BindException exception) {
HttpServletRequest request, BindException exception) { // 按需重新封装需要返回的错误信息
//按需重新封装需要返回的错误信息 List<ArgumentInvalidResult> invalidArguments = new ArrayList<>();
List<ArgumentInvalidResult> invalidArguments = new ArrayList<>(); // 解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息
//解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息 for (FieldError error : exception.getBindingResult().getFieldErrors()) {
for (FieldError error : exception.getBindingResult().getFieldErrors()) { ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult();
ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult(); invalidArgument.setDefaultMessage(error.getDefaultMessage());
invalidArgument.setDefaultMessage(error.getDefaultMessage()); invalidArgument.setField(error.getField());
invalidArgument.setField(error.getField()); invalidArgument.setRejectedValue(error.getRejectedValue());
invalidArgument.setRejectedValue(error.getRejectedValue()); invalidArguments.add(invalidArgument);
invalidArguments.add(invalidArgument); }
} Map<String, Object> body = new HashMap<>();
Map<String, Object> body = new HashMap<>(); body.put("errors", JsonUtils.objectToJson(invalidArguments));
body.put("errors", JsonUtils.objectToJson(invalidArguments)); body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
// body.put("path", request.getRequestURI()); // body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数错误", Convert.toStr(body)); return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数错误", Convert.toStr(body));
} }
/** /**
* 请求方式异常 * 请求方式异常
* *
* @param request 请求 * @param request 请求
* @param exception HttpRequestMethodNotSupportedException异常对象 * @param exception HttpRequestMethodNotSupportedException异常对象
* @return 响应 * @return 响应
*/ */
@ExceptionHandler(HttpRequestMethodNotSupportedException.class) @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
public BaseResponse<String> handleMethodNotSupportedException(HttpServletRequest request, HttpRequestMethodNotSupportedException exception) { public BaseResponse<String> handleMethodNotSupportedException(HttpServletRequest request,
Map<String, Object> body = new HashMap<>(); HttpRequestMethodNotSupportedException exception) {
body.put("errors", exception.getMessage()); Map<String, Object> body = new HashMap<>();
body.put("error", HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase()); body.put("errors", exception.getMessage());
body.put("error", HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase());
// body.put("path", request.getRequestURI()); // body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.METHOD_NOT_ALLOWED.value(), "错误的请求方式", Convert.toStr(body)); return BaseResponse.fail(HttpStatus.METHOD_NOT_ALLOWED.value(), "错误的请求方式", Convert.toStr(body));
} }
/** /**
* 参数缺失 * 参数缺失
* *
* @param request 请求 * @param request 请求
* @param exception MissingServletRequestParameterException异常对象 * @param exception MissingServletRequestParameterException异常对象
* @return 响应 * @return 响应
*/ */
@ExceptionHandler(MissingServletRequestParameterException.class) @ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleMissingParameterException(HttpServletRequest request, MissingServletRequestParameterException exception) { public BaseResponse<String> handleMissingParameterException(HttpServletRequest request,
Map<String, Object> body = new HashMap<>(); MissingServletRequestParameterException exception) {
body.put("errors", exception.getMessage()); Map<String, Object> body = new HashMap<>();
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase()); body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
// body.put("path", request.getRequestURI()); // body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数缺失" + exception.getMessage(), Convert.toStr(body)); return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数缺失" + exception.getMessage(), Convert.toStr(body));
} }
// ----------------------------data-------------------------------------- // ----------------------------data--------------------------------------
/** /**
* 数据库异常 * 数据库异常
* *
* @param request 请求 * @param request 请求
* @param exception DataAccessException异常对象 * @param exception DataAccessException异常对象
* @return 响应 * @return 响应
*/ */
@ExceptionHandler(DataAccessException.class) @ExceptionHandler(DataAccessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handlerDataAccessException(HttpServletRequest request, DataAccessException exception) { public BaseResponse<String> handlerDataAccessException(HttpServletRequest request, DataAccessException exception) {
log.error(ExceptionUtil.stacktraceToString(exception)); log.error(ExceptionUtil.stacktraceToString(exception));
Map<String, Object> body = new HashMap<>(); Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage()); body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase()); body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
// body.put("path", request.getRequestURI()); // body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据库异常" + exception.getMessage(), Convert.toStr(body)); return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据库异常" + exception.getMessage(), Convert.toStr(body));
} }
/** /**
* 数据不存在 * 数据不存在
* *
* @param request 请求 * @param request 请求
* @param exception EmptyResultDataAccessException异常对象 * @param exception EmptyResultDataAccessException异常对象
* @return 响应 * @return 响应
*/ */
@ExceptionHandler(EmptyResultDataAccessException.class) @ExceptionHandler(EmptyResultDataAccessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleDataEmptyException(HttpServletRequest request, EmptyResultDataAccessException exception) { public BaseResponse<String> handleDataEmptyException(HttpServletRequest request,
Map<String, Object> body = new HashMap<>(); EmptyResultDataAccessException exception) {
body.put("errors", exception.getMessage()); Map<String, Object> body = new HashMap<>();
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase()); body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
// body.put("path", request.getRequestURI()); // body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据不存在", Convert.toStr(body)); return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据不存在", Convert.toStr(body));
} }
/** /**
* 请求方式异常 * 请求方式异常
* *
* @param request 请求 * @param request 请求
* @param exception DuplicateKeyException异常对象 * @param exception DuplicateKeyException异常对象
* @return 响应 * @return 响应
*/ */
@ExceptionHandler(DuplicateKeyException.class) @ExceptionHandler(DuplicateKeyException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleDataDualException(HttpServletRequest request, DuplicateKeyException exception) { public BaseResponse<String> handleDataDualException(HttpServletRequest request, DuplicateKeyException exception) {
Map<String, Object> body = new HashMap<>(); Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage()); body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase()); body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
// body.put("path", request.getRequestURI()); // body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据重复插入", Convert.toStr(body)); return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据重复插入", Convert.toStr(body));
} }
/** /**
* 方法参数类型不匹配异常 * 方法参数类型不匹配异常
* *
* @param request 请求 * @param request 请求
* @param exception MethodArgumentTypeMismatchException异常对象 * @param exception MethodArgumentTypeMismatchException异常对象
* @return 响应 * @return 响应
*/ */
@ExceptionHandler(MethodArgumentTypeMismatchException.class) @ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleMethodArgumentTypeException(HttpServletRequest request, MethodArgumentTypeMismatchException exception) { public BaseResponse<String> handleMethodArgumentTypeException(HttpServletRequest request,
Map<String, Object> body = new HashMap<>(); MethodArgumentTypeMismatchException exception) {
body.put("errors", exception.getMessage()); Map<String, Object> body = new HashMap<>();
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase()); body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
// body.put("path", request.getRequestURI()); // body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数类型不匹配", Convert.toStr(body)); return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数类型不匹配", Convert.toStr(body));
} }
/** /**
* 全局异常处理 * 全局异常处理
* *
* @param request 请求 * @param request 请求
* @param exception Exception异常对象 * @param exception Exception异常对象
* @return 响应 * @return 响应
*/ */
@ExceptionHandler(value = Exception.class) @ExceptionHandler(value = Exception.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleException(HttpServletRequest request, Exception exception) { public BaseResponse<String> handleException(HttpServletRequest request, Exception exception) {
//堆栈信息转为字符串 // 堆栈信息转为字符串
log.info(ExceptionUtil.stacktraceToString(exception)); log.info(ExceptionUtil.stacktraceToString(exception));
Map<String, Object> body = new HashMap<>(); Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage()); body.put("errors", exception.getMessage());
body.put("error", HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()); body.put("error", HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase());
// body.put("path", request.getRequestURI()); // body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统异常:" + exception.getMessage(), Convert.toStr(body)); return BaseResponse.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统异常:" + exception.getMessage(),
} Convert.toStr(body));
}
@ExceptionHandler({TransactionSystemException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleTransactionSystemException(HttpServletRequest request, TransactionSystemException exception) {
log.info(ExceptionUtil.stacktraceToString(exception));
if (((String)Objects.requireNonNull(exception.getMessage())).contains("may be has finished")) {
String xid = RootContext.getXID();
if (StringUtils.isNotEmpty(xid)) {
RootContext.unbind();
log.debug("TransactionSystemException ----- suspending current transaction,xid = {}", xid);
}
}
return BaseResponse.fail("系统繁忙,请重试", exception.getMessage()); @ExceptionHandler({ TransactionSystemException.class, RmTransactionException.class })
} @ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleTransactionSystemException(HttpServletRequest request,
TransactionSystemException exception) {
log.info(ExceptionUtil.stacktraceToString(exception));
if (((String) Objects.requireNonNull(exception.getMessage())).contains("may be has finished")) {
String xid = RootContext.getXID();
if (StringUtils.isNotEmpty(xid)) {
RootContext.unbind();
log.debug("TransactionSystemException ----- suspending current transaction,xid = {}", xid);
}
}
/** return BaseResponse.fail("系统繁忙,请重试", exception.getMessage());
* 参数异常 }
*/
@Getter /**
@Setter * 参数异常
class ArgumentInvalidResult { */
/** @Getter
* 字段名 @Setter
*/ class ArgumentInvalidResult {
private String field; /**
/** * 字段名
* 输入的错误值 */
*/ private String field;
private Object rejectedValue; /**
/** * 输入的错误值
* 错误信息 */
*/ private Object rejectedValue;
private String defaultMessage; /**
} * 错误信息
*/
private String defaultMessage;
}
} }