1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
package io.github.lyr2000.dissertation.components;

import io.github.lyr2000.common.config.EnableExceptionHandler;
import io.github.lyr2000.common.dto.Result;
import io.github.lyr2000.common.dto.ViewObject;
import io.github.lyr2000.common.enums.DefaultApiCode;
import io.github.lyr2000.common.exception.ApiException;
import io.github.lyr2000.dissertation.enums.Err;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * @author LYR666
 * @description 异常处理器
 * @create 2021-11-04 22:01
 */
@Slf4j
// @EnableExceptionHandler
@Configuration
@RestControllerAdvice
public class CustomExceptionHandler {
    public static final String ERROR_INFO = "errorInfo";

    @org.springframework.web.bind.annotation.ExceptionHandler(value = SQLIntegrityConstraintViolationException.class)
    public Result handleMysqlDataError(SQLIntegrityConstraintViolationException exception) {
        log.info("dataERR := {}",exception.toString());
        return Result.of(Err.REPEAT_DATA,"插入异常,重复数据");
    }

    @org.springframework.web.bind.annotation.ExceptionHandler(value = {org.apache.shiro.authz.UnauthenticatedException.class})
    public Result noToken(UnauthenticatedException e) {
        log.info("require authenticate = {}",e.getMessage());
        return Result.of(DefaultApiCode.NO_TOKEN,"没有登录,出现异常");
    }

    //
    // @ExceptionHandler({Exception.class})
    // public Result wrapException(Exception e) {
    //     log.error("exception = {}",e.getMessage());
    //     return Result.of(DefaultApiCode.BASIC_ERROR,"出现严重异常");
    // }
    // @ExceptionHandler({ApiException.class})
    // public Result wrapAPIException(ApiException e) {
    //     log.error("exception = {}",e.getMessage());
    //     return new Result()
    //             .withCode(e.getCode())
    //             .withMessage(e.getMessage())
    //             ;
    // }


    /**
     * 参数校验异常
     */
    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public ViewObject validateException(MethodArgumentNotValidException ex) {
        String frontInfo = ex.getBindingResult()
                .getAllErrors()
                .stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.joining(";"));
        //将参数校验信息反馈给前端
        return ViewObject.of(DefaultApiCode.BAD_REQUEST)
                .put(ERROR_INFO,frontInfo);
    }

    /**
     * 参数校验异常
     * @param e
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ViewObject ConstraintViolationExceptionHandler(ConstraintViolationException e) {
        String message = e.getConstraintViolations()
                .stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining(";"));
        return ViewObject.of(DefaultApiCode.BAD_REQUEST)
                .put(ERROR_INFO,message);
    }

    /**
     * 前端 json报文有问题
     * @param e
     * @return
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ViewObject notReadable(HttpMessageNotReadableException e) {

        return ViewObject.of(DefaultApiCode.BAD_REQUEST)
                .put(ERROR_INFO,e.getMessage())
                .put("tips","请求的语法出错[字段不符合格式需求]");
    }


    /**
     * 不支持对应的 url 方法
     * @param ex
     * @return
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public ViewObject validateExceptionsss(HttpRequestMethodNotSupportedException ex) {
        log.info("http method not support");
        //将参数校验信息反馈给前端
        return ViewObject.of(DefaultApiCode.NO_RESOURCE)
                .put(ERROR_INFO,"请求方法不对")

                ;
    }

    /**
     *  基本异常,不知道什么异常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public ViewObject validateExceptionsssss(Exception ex) {

        //将参数校验信息反馈给前端
        return ViewObject.of(DefaultApiCode.BASIC_ERROR).put("errInfo",ex.getMessage());
    }


    // /**
    //  * 业务层 手动抛的异常
    //  * @param e
    //  * @return
    //  */
    // @ExceptionHandler(BusinessException.class)
    // public  ViewObject bussiness(BusinessException e) {
    //
    //     log.error("出现了runtime异常 {}",e.getMessage());
    //
    //     // System.out.println(e.getClass());
    //
    //
    //     return ViewObject.of(ApiInfo.SERVICE_UN_AVAILABLE)
    //             .put(ERROR_INFO,e.getMessage());
    // }


    /**
     * 运行时异常
     * @param e
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public  ViewObject runtimeEx(RuntimeException e) {

        log.error("出现了runtime异常 {}",e.getMessage());


        // System.out.println(e.getClass());


        return ViewObject.of(DefaultApiCode.BASIC_ERROR)
                .put(ERROR_INFO,e.getMessage());
    }


    /**
     * 空指针异常
     * @param e
     * @return
     */
    @ExceptionHandler(NullPointerException.class)
    public  ViewObject nullPointerEx(Exception e) {
        if( AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class)!=null) {
            //如果异常类上被打上了 ResponseStatus 注解,那么按照异常注解上的状态执行,抛出异常,交给 springboot 自动处理
            throw new RuntimeException(e);
        }
        log.error(Arrays.toString(e.getStackTrace()));
        log.error("出现了 空指针异常 {}",e.getMessage());

        // System.out.println(e.getClass());


        return ViewObject.of(DefaultApiCode.SERVER_ERROR)
                .put(ERROR_INFO,e.getMessage())
                .put("info","空指针异常");
    }

    // /**
    //  * shiro 权限校验异常
    //  * 权限不足
    //  * @param exception
    //  * @return
    //  */
    // @ExceptionHandler(UnauthorizedException.class)
    // public ViewObject unAuthError(UnauthorizedException exception) {
    //     return ViewObject
    //             .of(ApiInfo.FORBIDDEN_REQUEST)
    //             .put(ERROR_INFO,exception.getMessage());
    // }


    // /**
    //  * json 格式异常
    //  * @param e
    //  * @return
    //  */
    // @ExceptionHandler(RequestBodyErrorException.class)
    // public ViewObject jsonBodyErr(RequestBodyErrorException e) {
    //
    //     return ViewObject.of(ApiInfo.BAD_REQUEST)
    //             .put(ERROR_INFO,e.getMessage())
    //             .put("tips","请求体不符合要求,不是json或者不是formData");
    // }

    /**
     * 运行时异常
     * @param e
     * @return
     */
    @ExceptionHandler(ApiException.class)
    public ViewObject runtimeEx(ApiException e) {

        log.error("出现了runtime异常 {}",e.getMessage());


        // System.out.println(e.getClass());


        return new ViewObject()
                .setCode(e.getCode())
                .setMessage(e.getMessage());

    }

    /**
     * @return 路由参数绑定异常
     */
    @org.springframework.web.bind.annotation.ExceptionHandler(ServletRequestBindingException.class)
    public ViewObject bindingException(ServletRequestBindingException ex) {
        return ViewObject.of(DefaultApiCode.RouterBindingException);
    }

    @org.springframework.web.bind.annotation.ExceptionHandler(NoHandlerFoundException.class)
    public ViewObject noHandlerException(NoHandlerFoundException ex) {
        return ViewObject.of(DefaultApiCode.NoHandlerException);
    }

    /**
     * shiro框架
     * 权限不足
     * @param exception
     * @return
     */
    @ExceptionHandler(org.apache.shiro.authz.UnauthorizedException.class)
    public ViewObject unAuthError(UnauthorizedException exception) {
        return ViewObject
                .of(DefaultApiCode.FORBIDDEN_REQUEST)
                .put(ERROR_INFO,exception.getMessage());
    }

}