前言
今天要给大家介绍的是如何告别业务代码中大量的try-catch,让你专注于业务代码而不用考虑异常处理。
大家是不是在业务代码里面经常看到这种代码:
/**
* 坏的案例
*
* @return
*/
@RequestMapping(value = "/base-case")
public ActionResult baseCase() {
try {
// 业务处理
// ...
} catch (BusinessException e) {
log.info("业务发生异常", e);
return ActionResult.fail(e.getCode(), e.getMessage());
} catch (Exception e) {
log.info("业务发生异常", e);
return ActionResult.fail(CommonExceptionEnum.SYSTEM_ERROR.getCode(), e.getMessage());
}
return ActionResult.isSuccess();
}
在每个类里都写上这些代码,不仅仅看起来丑陋,后续维护也非常麻烦,万一要改个异常或者日志,要改一万个地方。
今天我要手把手教大家使用使用统一拦截器来告别这种丑陋的代码。
最佳实践
基本思路使用spring
提供的ExceptionHandler
注解来统一拦截异常,并返回给前端。
直接上案例
这里需要配合 “统一 Reuslt
对象去封装返回值” 一起使用,可以打开 https://github.com/zhuangjiaju/easytools 找到案例
业务代码中直接抛出异常即可
/**
* demo/异常模板
*
* @author Jiaju Zhuang
*/
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/web/result")
public class ExceptionWebController {
/**
* 测试业务异常
*
* @return
*/
@GetMapping("business-exception")
public ActionResult businessException() {
// 直接抛出异常,不用返回ActionResult
throw BusinessException.of("业务异常");
}
/**
* 测试系统异常
*
* @return
*/
@GetMapping("system-exception")
public ActionResult systemException() {
// 直接抛出异常,不用返回ActionResult
throw SystemException.of("系统异常");
}
}
返回的结果:
{
"success": false,
"errorCode": "BUSINESS_ERROR",
"errorMessage": "业务异常",
"traceId": null
}
{
"success": false,
"errorCode": "SYSTEM_ERROR",
"errorMessage": "系统开小差啦,请尝试刷新页面或者联系管理员",
"traceId": null
}
输出的异常日志:
2024-07-04T20:54:40.903+08:00 INFO 17360 --- [nio-8080-exec-1] c.g.z.e.w.c.h.ControllerExceptionHandler : 发生业务异常/api/web/result/business-exception:ActionResult(success=false, errorCode=BUSINESS_ERROR, errorMessage=业务异常, traceId=null)
com.github.zhuangjiaju.easytools.tools.base.excption.BusinessException: 业务异常
at com.github.zhuangjiaju.easytools.tools.base.excption.BusinessException.of(BusinessException.java:47)
at com.github.zhuangjiaju.easytools.web.web.contoller.exception.ExceptionWebController.businessException(ExceptionWebController.java:30)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
at org.apache.catalina.core