//异常测试
@ApiOperation(value = "异常测试")
@GetMapping("exceptionTest")
public R exceptionTest(){
int a = 1/0;
return R.ok();
}
2、什么是统一异常处理
我们想让异常结果也显示为统一的返回结果对象,并且统一处理系统的异常信息,那么需要统一异常处理。
二、统一异常处理
package com.stu.service.base.handler;
import com.stu.service.base.exception.CustomException;
import com.stu.service.base.result.R;
import com.stu.service.base.utils.ExceptionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/******************************
* 用途说明:统一异常处理
* 作者姓名: Administrator
* 创建时间: 2022-04-17 23:32
******************************/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
/***********************************
* 用途说明:自定义异常
* 返回值说明: com.stu.service.base.result.R
***********************************/
@ExceptionHandler(CustomException.class)
@ResponseBody
public R customException(CustomException e){
// e.printStackTrace();
log.error(e.getMessage());
log.error(ExceptionUtils.getMessage(e));
return R.error().message(e.getMessage()).code(e.getCode());
}
/***********************************
* 用途说明:数字异常
* 返回值说明: com.stu.service.base.result.R
***********************************/
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public R arithmeticException(Exception e){
log.error(ExceptionUtils.getMessage(e));
return R.error().message(e.getMessage());
}
/***********************************
* 用途说明:全局异常
* 返回值说明: com.stu.service.base.result.R
***********************************/
@ExceptionHandler(Exception.class)
@ResponseBody
public R error(Exception e){
log.error(ExceptionUtils.getMessage(e));
return R.error().message(e.getMessage());
}
}
package com.stu.service.base.exception;
import com.stu.service.base.result.ResultCodeEnum;
import lombok.Data;
/******************************
* 用途说明:自定义异常
* 作者姓名: Administrator
* 创建时间: 2022-04-18 0:00
******************************/
@Data
public class CustomException extends RuntimeException{
private Integer code;
public CustomException(ResultCodeEnum resultCodeEnum){
super(resultCodeEnum.getMessage());
//this.message = resultCodeEnum.getMessage();
this.code = resultCodeEnum.getCode();
}
}
package com.stu.service.base.result;
import lombok.Getter;
import lombok.ToString;
/**
* 前后端数据交换状态码
*/
@Getter
@ToString
public enum ResultCodeEnum {
SUCCESS(true, 20000, "成功"),
UNKNOWN_REASON(false, 20001, "未知错误"),
UPDATE_ERROR(false, 20002, "更新失败"),
BAD_SQL_GRAMMAR(false, 21001, "sql 语法错误"),
JSON_PARSE_ERROR(false, 21002, "json 解析异常"),
PARAM_ERROR(false, 21003, "参数不正确"),
FILE_UPLOAD_ERROR(false, 21004, "文件上传错误"),
FILE_DELETE_ERROR(false, 21005, "文件刪除错误"),
EXCEL_DATA_IMPORT_ERROR(false, 21006, "Excel 数据导入错误"),
VIDEO_UPLOAD_ALIYUN_ERROR(false, 22001, "视频上传至阿里云失败"),
VIDEO_UPLOAD_TOMCAT_ERROR(false, 22002, "视频上传至业务服务器失败"),
VIDEO_DELETE_ALIYUN_ERROR(false, 22003, "阿里云视频文件删除失败"),
FETCH_VIDEO_UPLOADAUTH_ERROR(false, 22004, "获取上传地址和凭证失败"),
REFRESH_VIDEO_UPLOADAUTH_ERROR(false, 22005, "刷新上传地址和凭证失败"),
FETCH_PLAYAUTH_ERROR(false, 22006, "获取播放凭证失败"),
URL_ENCODE_ERROR(false, 23001, "URL编码失败"),
ILLEGAL_CALLBACK_REQUEST_ERROR(false, 23002, "非法回调请求"),
FETCH_ACCESSTOKEN_FAILD(false, 23003, "获取 accessToken 失败"),
FETCH_USERINFO_ERROR(false, 23004, "获取用户信息失败"),
LOGIN_ERROR(false, 23005, "登录失败"),
COMMENT_EMPTY(false, 24006, "评论内容必须填写"),
PAY_RUN(false, 25000, "支付中"),
PAY_UNIFIEDORDER_ERROR(false, 25001, "统一下单错误"),
PAY_ORDERQUERY_ERROR(false, 25002, "查询支付结果错误"),
ORDER_EXIST_ERROR(false, 25003, "课程已购买"),
GATEWAY_ERROR(false, 26000, "服务不能访问"),
CODE_ERROR(false, 28000, "验证码错误"),
LOGIN_PHONE_ERROR(false, 28009, "手机号码不正确"),
LOGIN_MOBILE_ERROR(false, 28001, "账号不正确"),
LOGIN_PASSWORD_ERROR(false, 28008, "密码不正确"),
LOGIN_DISABLED_ERROR(false, 28002, "该用户已被禁用"),
REGISTER_MOBLE_ERROR(false, 28003, "手机号已被注册"),
LOGIN_AUTH(false, 28004, "需要登录"),
LOGIN_ACL(false, 28005, "没有权限"),
SMS_SEND_ERROR(false, 28006, "短信发送失败"),
SMS_SEND_ERROR_BUSINESS_LIMIT_CONTROL(false, 28007, "短信发送过于频繁"),
DIVIDE_ZERO(false, 29001, "除零错误"),
DATA_NULL(false, 30001, "数据不存在!"),
DATA_EXITS(false, 30002, "数据已存在!"),
DATA_NODE_EXITS(false, 30003, "该章节下存在视频课程,请先删除视频课程!");
private final Boolean success;
private final Integer code;
private final String message;
ResultCodeEnum(Boolean success, Integer code, String message) {
this.success = success;
this.code = code;
this.message = message;
}
}
CustomException
package com.stu.service.edu.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.stu.service.base.exception.CustomException;
import com.stu.service.base.result.ResultCodeEnum;
import com.stu.service.edu.entity.Chapter;
import com.stu.service.edu.entity.Video;
import com.stu.service.edu.entity.vo.ChapterVo;
import com.stu.service.edu.mapper.ChapterMapper;
import com.stu.service.edu.service.ChapterService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.stu.service.edu.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 课程 服务实现类
* </p>
*
* @author stu
* @since 2022-05-08
*/
@Service
public class ChapterServiceImpl extends ServiceImpl<ChapterMapper, Chapter> implements ChapterService {
@Autowired
private ChapterMapper chapterMapper;
@Autowired
private VideoService videoService;
/***********************************
* 用途说明:课程章节信息
* 返回值说明: java.util.List<com.stu.service.edu.entity.vo.ChapterVo>
***********************************/
@Override
public List<ChapterVo> listChapters(String courseId) {
return chapterMapper.listChapters(courseId);
}
/***********************************
* 用途说明:删除课程章节,判断是否有视频,有的话不能删除
* 返回值说明: boolean
***********************************/
@Override
public boolean removeById(String id) {
QueryWrapper<Video> queryWrapper = new QueryWrapper();
queryWrapper.eq("chapter_id",id);
int count = videoService.count(queryWrapper);
if(count > 0 ){
throw new CustomException(ResultCodeEnum.DATA_NODE_EXITS);
}
return baseMapper.deleteById(id) > 0;
}
}
5、ExceptionUtils
package com.stu.service.base.utils;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
/******************************
* 用途说明:
* 作者姓名: Administrator
* 创建时间: 2022-04-18 22:26
******************************/
public class ExceptionUtils {
/***********************************
* 用途说明:
* 返回值说明: java.lang.String
***********************************/
public static String getMessage(Exception e) {
StringWriter sw = null;
PrintWriter pw = null;
try {
sw = new StringWriter();
pw = new PrintWriter(sw);
// 将出错的栈信息输出到printWriter中
e.printStackTrace(pw);
pw.flush();
sw.flush();
} finally {
if (sw != null) {
try {
sw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (pw != null) {
pw.close();
}
}
return sw.toString();
}
}
6、测试除零异常
启动程序,访问带有除零异常的接口,在自定义异常类里输出3种log,分别输出e.getMessage(),ExceptionUtils.getMessage(e),e
/***********************************
* 用途说明:数字异常
* 返回值说明: com.stu.service.base.result.R
***********************************/
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public R arithmeticException(Exception e){
// e.printStackTrace();
log.error("e.getMessage() ==START=== "+e.getMessage()+" ==END=== ");
log.error("ExceptionUtils.getMessage(e) ==========START=== "+ExceptionUtils.getMessage(e)+" ==END=== ");
log.error("eeeeeeeeeeee ==========START=== "+e+" ==END=== ");
return R.error().message(e.getMessage());
}
输出log
2022-10-15 15:50:34 |ERROR |http-nio-9110-exec-6 |GlobalExceptionHandler.java:41 |com.stu.service.base.handler.GlobalExceptionHandler |e.getMessage() ==START=== / by zero ==END===
2022-10-15 15:50:36 |ERROR |http-nio-9110-exec-6 |GlobalExceptionHandler.java:42 |com.stu.service.base.handler.GlobalExceptionHandler |ExceptionUtils.getMessage(e) ==========START=== java.lang.ArithmeticException: / by zero
at com.stu.service.edu.controller.admin.TeacherController.findAllTeacher(TeacherController.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:744)
==END===
2022-10-15 15:50:36 |ERROR |http-nio-9110-exec-6 |GlobalExceptionHandler.java:43 |com.stu.service.base.handler.GlobalExceptionHandler |eeeeeeeeeeee ==========START=== java.lang.ArithmeticException: / by zero ==END===