懒羊羊
2023-08-30 71e81ed1d12e4d69f53c8ad9e066650ad4186293
提交 | 用户 | 时间
71e81e 1 /**
2  * Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
3  * <p>
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * <p>
8  * http://www.apache.org/licenses/LICENSE-2.0
9  * <p>
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package cn.stylefeng.guns.sys.core.exception.aop;
17
18 import cn.stylefeng.guns.base.auth.context.LoginContextHolder;
19 import cn.stylefeng.guns.base.auth.exception.AuthException;
20 import cn.stylefeng.guns.base.auth.exception.PermissionException;
21 import cn.stylefeng.guns.base.auth.exception.enums.AuthExceptionEnum;
22 import cn.stylefeng.guns.sys.core.exception.DemoException;
23 import cn.stylefeng.guns.sys.core.exception.InvalidKaptchaException;
24 import cn.stylefeng.guns.sys.core.exception.enums.BizExceptionEnum;
25 import cn.stylefeng.guns.sys.core.log.LogManager;
26 import cn.stylefeng.guns.sys.core.log.factory.LogTaskFactory;
27 import cn.stylefeng.roses.kernel.model.exception.ServiceException;
28 import cn.stylefeng.roses.kernel.model.response.ErrorResponseData;
29 import lombok.extern.slf4j.Slf4j;
30 import org.apache.ibatis.exceptions.PersistenceException;
31 import org.hibernate.validator.internal.engine.path.PathImpl;
32 import org.mybatis.spring.MyBatisSystemException;
33 import org.springframework.core.annotation.Order;
34 import org.springframework.http.HttpStatus;
35 import org.springframework.http.converter.HttpMessageNotReadableException;
36 import org.springframework.validation.BindException;
37 import org.springframework.validation.BindingResult;
38 import org.springframework.validation.FieldError;
39 import org.springframework.web.bind.MethodArgumentNotValidException;
40 import org.springframework.web.bind.MissingServletRequestParameterException;
41 import org.springframework.web.bind.annotation.ControllerAdvice;
42 import org.springframework.web.bind.annotation.ExceptionHandler;
43 import org.springframework.web.bind.annotation.ResponseBody;
44 import org.springframework.web.bind.annotation.ResponseStatus;
45 import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
46
47 import javax.validation.ConstraintViolation;
48 import javax.validation.ConstraintViolationException;
49 import java.util.Set;
50
51 import static cn.stylefeng.roses.core.util.HttpContext.getIp;
52 import static cn.stylefeng.roses.core.util.HttpContext.getRequest;
53
54 /**
55  * 全局的的异常拦截器(拦截所有的控制器)(带有@RequestMapping注解的方法上都会拦截)
56  *
57  * @author fengshuonan
58  * @date 2016年11月12日 下午3:19:56
59  */
60 @ControllerAdvice
61 @Order(-100)
62 @Slf4j
63 public class GlobalExceptionHandler {
64
65     /**
66      * 参数校验错误
67      *
68      * @author fengshuonan
69      * @Date 2020/2/5 11:50 下午
70      */
71     @ExceptionHandler(MissingServletRequestParameterException.class)
72     @ResponseStatus(HttpStatus.BAD_REQUEST)
73     @ResponseBody
74     public ErrorResponseData handleError(MissingServletRequestParameterException e) {
75         log.warn("Missing Request Parameter", e);
76         String message = String.format("Missing Request Parameter: %s", e.getParameterName());
77         return new ErrorResponseData(400, message);
78     }
79
80     /**
81      * 参数校验错误
82      *
83      * @author fengshuonan
84      * @Date 2020/2/6 10:18 上午
85      */
86     @ExceptionHandler(MethodArgumentTypeMismatchException.class)
87     @ResponseStatus(HttpStatus.BAD_REQUEST)
88     @ResponseBody
89     public ErrorResponseData handleError(MethodArgumentTypeMismatchException e) {
90         log.warn("Method Argument Type Mismatch", e);
91         String message = String.format("Method Argument Type Mismatch: %s", e.getName());
92         return new ErrorResponseData(400, message);
93     }
94
95     /**
96      * 参数校验错误
97      *
98      * @author fengshuonan
99      * @Date 2020/2/6 10:19 上午
100      */
101     @ExceptionHandler(MethodArgumentNotValidException.class)
102     @ResponseStatus(HttpStatus.BAD_REQUEST)
103     @ResponseBody
104     public ErrorResponseData handleError(MethodArgumentNotValidException e) {
105         log.warn("Method Argument Not Valid", e);
106         BindingResult result = e.getBindingResult();
107         FieldError error = result.getFieldError();
108         String message = String.format("%s:%s", error.getField(), error.getDefaultMessage());
109         return new ErrorResponseData(400, message);
110     }
111
112     /**
113      * 参数校验错误异常
114      *
115      * @author fengshuonan
116      * @Date 2020/2/6 9:49 上午
117      */
118     @ExceptionHandler(BindException.class)
119     @ResponseStatus(HttpStatus.BAD_REQUEST)
120     @ResponseBody
121     public ErrorResponseData handleError(BindException e) {
122         log.warn("Bind Exception", e);
123         FieldError error = e.getFieldError();
124         String message = String.format("%s:%s", error.getField(), error.getDefaultMessage());
125         return new ErrorResponseData(400, message);
126     }
127
128     /**
129      * 参数校验错误异常
130      *
131      * @author fengshuonan
132      * @Date 2020/2/8 12:20
133      */
134     @ExceptionHandler(ConstraintViolationException.class)
135     @ResponseStatus(HttpStatus.BAD_REQUEST)
136     @ResponseBody
137     public ErrorResponseData handleError(ConstraintViolationException e) {
138         log.warn("Constraint Violation", e);
139         Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
140         ConstraintViolation<?> violation = violations.iterator().next();
141         String path = ((PathImpl) violation.getPropertyPath()).getLeafNode().getName();
142         String message = String.format("%s:%s", path, violation.getMessage());
143         return new ErrorResponseData(400, message);
144     }
145
146     /**
147      * 参数校验错误异常
148      *
149      * @author fengshuonan
150      * @Date 2020/2/6 9:49 上午
151      */
152     @ExceptionHandler(HttpMessageNotReadableException.class)
153     @ResponseStatus(HttpStatus.BAD_REQUEST)
154     @ResponseBody
155     public ErrorResponseData handleError(HttpMessageNotReadableException e) {
156         log.warn("HttpMessageNotReadableException ", e);
157         String message = String.format("HttpMessageNotReadableException:%s", e.getMessage());
158         return new ErrorResponseData(400, message);
159     }
160
161     /**
162      * 认证异常--认证失败(账号密码错误,账号被冻结,token过期等)
163      *
164      * @author fengshuonan
165      * @Date 2020/2/6 11:14 上午
166      */
167     @ExceptionHandler(AuthException.class)
168     @ResponseStatus(HttpStatus.UNAUTHORIZED)
169     @ResponseBody
170     public ErrorResponseData unAuth(AuthException e) {
171         return new ErrorResponseData(e.getCode(), e.getMessage());
172     }
173
174     /**
175      * 认证异常--没有访问权限
176      *
177      * @author fengshuonan
178      * @Date 2020/2/6 11:14 上午
179      */
180     @ExceptionHandler(PermissionException.class)
181     @ResponseStatus(HttpStatus.UNAUTHORIZED)
182     @ResponseBody
183     public ErrorResponseData permissionExpection(PermissionException e) {
184         return new ErrorResponseData(e.getCode(), e.getMessage());
185     }
186
187     /**
188      * 验证码错误异常
189      *
190      * @author fengshuonan
191      * @Date 2020/2/6 11:14 上午
192      */
193     @ExceptionHandler(InvalidKaptchaException.class)
194     @ResponseStatus(HttpStatus.BAD_REQUEST)
195     @ResponseBody
196     public ErrorResponseData credentials(InvalidKaptchaException e) {
197         String username = getRequest().getParameter("username");
198         LogManager.me().executeLog(LogTaskFactory.loginLog(username, "验证码错误", getIp()));
199         return new ErrorResponseData(AuthExceptionEnum.VALID_CODE_ERROR.getCode(), AuthExceptionEnum.VALID_CODE_ERROR.getMessage());
200     }
201
202     /**
203      * 拦截业务异常
204      *
205      * @author fengshuonan
206      * @Date 2020/2/6 11:14 上午
207      */
208     @ExceptionHandler(ServiceException.class)
209     @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
210     @ResponseBody
211     public ErrorResponseData bussiness(ServiceException e) {
212         log.error("业务异常:", e);
213         if (LoginContextHolder.getContext().hasLogin()) {
214             LogManager.me().executeLog(LogTaskFactory.exceptionLog(LoginContextHolder.getContext().getUserId(), e));
215         }
216         getRequest().setAttribute("tip", e.getMessage());
217         return new ErrorResponseData(e.getCode(), e.getMessage());
218     }
219
220     /**
221      * 拦截mybatis数据库操作的异常
222      * <p>
223      * 用在demo模式,拦截DemoException
224      *
225      * @author stylefeng
226      * @date 2020/5/5 15:19
227      */
228     @ExceptionHandler(MyBatisSystemException.class)
229     @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
230     @ResponseBody
231     public ErrorResponseData persistenceException(MyBatisSystemException e) {
232         Throwable cause = e.getCause();
233         if (cause instanceof PersistenceException) {
234             Throwable secondCause = cause.getCause();
235             if (secondCause instanceof DemoException) {
236                 DemoException demoException = (DemoException) secondCause;
237                 return new ErrorResponseData(demoException.getCode(), demoException.getMessage());
238             }
239         }
240         return new ErrorResponseData(500, "服务器异常");
241     }
242
243     /**
244      * 拦截未知的运行时异常
245      *
246      * @author fengshuonan
247      * @Date 2020/2/6 11:15 上午
248      */
249     @ExceptionHandler(Throwable.class)
250     @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
251     @ResponseBody
252     public ErrorResponseData notFount(Throwable e) {
253         log.error("运行时异常:", e);
254         if (LoginContextHolder.getContext().hasLogin()) {
255             LogManager.me().executeLog(LogTaskFactory.exceptionLog(LoginContextHolder.getContext().getUserId(), e));
256         }
257         String message = String.format("服务器未知运行时异常: %s", e.getMessage());
258         getRequest().setAttribute("tip", message);
259         return new ErrorResponseData(BizExceptionEnum.SERVER_ERROR.getCode(), message);
260     }
261 }