看到一篇处理方式比较清爽的,单做一个记录
原地址:如何优雅的处理全局异常
前言
异常处理是项目开发中绕不过的一个环节,一个优雅的全局异常处理可以迅速反馈给开发人员这些信息
1、异常种类
2、可能导致异常的原因
3、导致异常出现的关键参数
4、异常发生的时间
5、发生异常的请求路径
这些信息有助于开发人员迅速定位、处理异常,一个优秀的项目应该尽可能的将可能发生的异常进行捕获,再通过自定义的处理流程将异常信息反馈,而不是一味的抛出异常。
异常捕获流程
通常我们可以构建message和枚举类来管理异常种类,这样可以在写代码处理异常时让程序员更高程度的关注于业务
CodeEnum错误枚举类
/**
* @author
*/
@Getter
@AllArgsConstructor
public enum CodeEnum {
RESOURCE_NOT_FOUNT(1001, HttpStatus.HTTP_NOT_FOUND,"未找到该资源"),
PARAMS_FORMAT_INVALID(1002,HttpStatus.HTTP_BAD_REQUEST,"请求参数格式错误");
/**
* 自定义业务code
*/
private final int code;
/**
* http状态码
*/
private final int httpStatus;
/**
* 返回信息
*/
private final String message;
}
基础异常对象
BaseException 是所有自定义异常的父类,它规范了异常的基本结构由 CodeEnum 和 Map(附加信息)组成
@Data
@NoArgsConstructor
public class BaseException extends RuntimeException {
private CodeEnum codeEnum;
private final Map<String, Object> detail = new HashMap<>();
public BaseException(CodeEnum codeEnum) {
this.codeEnum = codeEnum;
}
public BaseException(CodeEnum codeEnum, Map<String, Object> params) {
this.codeEnum = codeEnum;
if (!ObjectUtils.isEmpty(params)) {
this.detail.putAll(params);
}
}
public BaseException(CodeEnum codeEnum, String msg) {
this.codeEnum = codeEnum;
HashMap<String, String> map = new HashMap<>();
map.put("description", msg);
detail.putAll(map);
}
}
ErrorResponse异常响应
定义一个异常视图对象,构建异常的基本信息,比如时间,请求路径等,该对象接收一个 BaseException 异常类。
/**
* 异常响应类
* @author
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ErrorResponse {
private Integer code;
private Integer httpStatus;
private String message;
private String path;
private Instant timestamp;
private Map<String, Object> detail = new HashMap<>();
public ErrorResponse(BaseException e, String path) {
this.code = e.getCodeEnum().getCode();
this.httpStatus = e.getCodeEnum().getHttpStatus();
this.timestamp = Instant.now();
this.path = path;
this.message = e.getCodeEnum().getMessage();
if (ObjectUtils.isEmpty(e.getDetail())){
this.detail.put("description", "");
}else {
this.detail.putAll(e.getDetail());
}
Result全局返回对象
一个项目的请求返回对象应该做到全局统一,这样开发的时候就不用纠结到底该返回哪个对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {
private Boolean success;
private T data;
public static Result<Object> ok() {
return new Result<>(true, null);
}
public static Result<String> ok(String msg) {
return new Result<>(true, msg);
}
public static Result<Object> ok(Object data) {
return new Result<>(true, data);
}
public static Result<Object> error() {
return new Result<>(false, null);
}
public static Result<String> error(String msg) {
return new Result<>(false, msg);
}
public static Result<ErrorResponse> error(ErrorResponse error) {
return new Result<>(false, error);
}
}
GlobalExceptionHandler异常捕获类
@RestControllerAdvice
public class GlobalExceptionHandler {
// 表示处理BaseException.class这个类型的异常
@ExceptionHandler(BaseException.class)
public Result<ErrorResponse> baseException(BaseException e, HttpServletRequest request) {
ErrorResponse errorResponse = new ErrorResponse(e,request.getRequestURI());
return Result.error(errorResponse);
}
}
测试
@RestController
@RequestMapping(value = "/test/ex", produces = MediaType.APPLICATION_JSON_VALUE)
public class ExceptionController {
@GetMapping("/resource")
public Result<Object> resource() {
throw new BaseException(CodeEnum.RESOURCE_NOT_FOUNT);
}
@PostMapping("/resource")
public Result<Object> resource(@RequestBody User user) {
throw new BaseException(CodeEnum.PARAMS_FORMAT_INVALID,
ImmutableMap.of("name", user.getName(),
"age", user.getAge(),
"email", user.getEmail()));
}
@GetMapping("/id")
public Result<Object> test(@Param("id") String id) {
if (id.length() > 5) {
throw new BaseException(CodeEnum.RESOURCE_NOT_FOUNT, "The invalid id is:\r\n" + id);
} else {
return Result.ok();
}
}
本文介绍了一种优雅的全局异常处理方案,通过自定义异常枚举、异常对象及响应类,实现异常信息的有效管理和反馈。此方案能快速帮助开发者定位问题,提升开发效率。
328

被折叠的 条评论
为什么被折叠?



