张晓波
2023-09-19 164694c47c35d6654df69b533e8dbf8b5423efc5
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
package com.thhy.general.exception;
 
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.util.StringUtil;
import com.thhy.general.common.BasicMessage;
import com.thhy.general.utils.UUIDUtils;
import com.thhy.general.common.BasicResult;
import com.thhy.general.common.BasicStatus;
import feign.FeignException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.StringWriter;
 
/**
 * @Author: zhang_xiao_bo
 * @Date: 2022/3/22 16:43
 * @description: controller 监听异常配置
 */
@RestControllerAdvice
public class ExceptionController {
 
    private static Logger log = LoggerFactory.getLogger(ExceptionController.class);
 
    @ExceptionHandler(Exception.class)
    public BasicResult handleException(HttpServletRequest request, HttpServletResponse response, Exception exception) {
        //如果有框架把自定义异常又封装成了系统异常,则需要重新指向自定义处理流程
        if(exception instanceof BasicException){
            return handleBusinessException(request,response,(BasicException)exception);
        }
        if(exception instanceof FeignException){
            return handleFeignException(request,response,(FeignException) exception);
        }
        if(exception instanceof MethodArgumentNotValidException){
            System.out.println("ssss");
        }
        //异常日志ID
        String errorLogId= UUIDUtils.create();
        //日志堆栈
        String stackTrace=getInfo(exception);
 
        //装配异常消息,异步发送
        ExceptionMessage exceptionMessage=new ExceptionMessage();
        //exceptionMessage.setAddress(serverConfig.getUrl());
        exceptionMessage.setRequestUri(request.getRequestURI());
        exceptionMessage.setErrorLogId(errorLogId);
        exceptionMessage.setStatusCode(BasicStatus.ERROR.statusCode());
        exceptionMessage.setStatusMsg(BasicStatus.ERROR.statusMsg());
        exceptionMessage.setStackTraceMsg(stackTrace);
 
        log.error("请求: " + request.getRequestURI() + " 引起异常:");
        log.error("日志编码:"+exceptionMessage.getErrorLogId());
        log.error("状态码:"+exceptionMessage.getStatusCode());
        log.error("状态说明:"+exceptionMessage.getStatusMsg());
        log.error(stackTrace);
 
 
 
        response.setStatus(HttpStatus.OK.value());
 
        return new BasicResult(false,BasicStatus.ERROR,new JSONObject());
    }
 
    /**
     * 自定义业务异常处理
     * @param request
     * @param response
     * @param exception
     * @return
     */
    @ExceptionHandler(BasicException.class)
    public BasicResult handleBusinessException(HttpServletRequest request, HttpServletResponse response, BasicException exception) {
        //日志堆栈,方法体中主动抛出的,还是catch中抛出的,二者不同
        String stackTrace= StringUtil.isEmpty(exception.getStackTraceMsg())?getInfo(exception):exception.getStackTraceMsg();
 
        //装配异常消息,异步发送
        ExceptionMessage exceptionMessage=new ExceptionMessage();
        //exceptionMessage.setAddress(serverConfig.getUrl());
        exceptionMessage.setRequestUri(request.getRequestURI());
        exceptionMessage.setErrorLogId(exception.getErrorLogId());
        exceptionMessage.setStatusCode(exception.getBasicStatus().statusCode());
        exceptionMessage.setStatusMsg(exception.getBasicStatus().statusMsg());
        exceptionMessage.setStackTraceMsg(stackTrace);
 
        log.error("请求: " + request.getRequestURI() + " 引起异常:");
        log.error("日志编码:"+exception.getErrorLogId());
        log.error("状态码:"+exception.getBasicStatus().statusCode());
        log.error("状态说明:"+exception.getBasicStatus().statusMsg());
        log.error(stackTrace);
 
        response.setStatus(HttpStatus.OK.value());
 
        return new BasicResult(false,exception.getBasicStatus(),new JSONObject());
    }
 
    /**
     * 自定义业务异常处理
     * @param request
     * @param response
     * @param exception
     * @return
     */
    @ExceptionHandler(FeignException.class)
    public BasicResult handleFeignException(HttpServletRequest request, HttpServletResponse response, FeignException exception) {
        //日志堆栈,方法体中主动抛出的,还是catch中抛出的,二者不同
        /*String stackTrace= StringUtils.isBlank(exception.getStackTraceMsg())?getInfo(exception):exception.getStackTraceMsg();
 
        //装配异常消息,异步发送
        ExceptionMessage exceptionMessage=new ExceptionMessage();
        exceptionMessage.setAddress(serverConfig.getUrl());
        exceptionMessage.setRequestUri(request.getRequestURI());
        exceptionMessage.setErrorLogId(exception.getErrorLogId());
        exceptionMessage.setStatusCode(exception.getBasicStatus().statusCode());
        exceptionMessage.setStatusMsg(exception.getBasicStatus().statusMsg());
        exceptionMessage.setStackTraceMsg(stackTrace);
 
        log.error("请求: " + request.getRequestURI() + " 引起异常:");
        log.error("日志编码:"+exception.get());
        log.error("状态码:"+exception.getBasicStatus().statusCode());
        log.error("状态说明:"+exception.getBasicStatus().statusMsg());
        log.error(stackTrace);*/
        String feignUrl = exception.request().url();
        String suff = feignUrl.split("//")[1];
        String serviceName = suff.substring(0,suff.indexOf("/"));
        String statusMsg = "feign调用"+serviceName+"出现异常";
        if(exception.status()==503){
            statusMsg=serviceName+"服务可能下线";
        }
 
        response.setStatus(HttpStatus.OK.value());
 
        return new BasicResult(false,new BasicMessage("00900",statusMsg),exception.getMessage());
    }
 
 
 
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public BasicResult handleValidException(HttpServletRequest request, HttpServletResponse response, BasicException exception) {
        //日志堆栈,方法体中主动抛出的,还是catch中抛出的,二者不同
        String stackTrace= StringUtil.isEmpty(exception.getStackTraceMsg())?getInfo(exception):exception.getStackTraceMsg();
        //装配异常消息,异步发送
        ExceptionMessage exceptionMessage=new ExceptionMessage();
        //exceptionMessage.setAddress(serverConfig.getUrl());
        exceptionMessage.setRequestUri(request.getRequestURI());
        exceptionMessage.setErrorLogId(exception.getErrorLogId());
        exceptionMessage.setStatusCode(exception.getBasicStatus().statusCode());
        exceptionMessage.setStatusMsg(exception.getBasicStatus().statusMsg());
        exceptionMessage.setStackTraceMsg(stackTrace);
 
        log.error("请求: " + request.getRequestURI() + " 引起异常:");
        log.error("日志编码:"+exception.getErrorLogId());
        log.error("状态码:"+exception.getBasicStatus().statusCode());
        log.error("状态说明:"+exception.getBasicStatus().statusMsg());
        log.error(stackTrace);
 
        response.setStatus(HttpStatus.OK.value());
 
        return new BasicResult(false,exception.getBasicStatus(),new JSONObject());
    }
 
    /**
     * 获取异常的堆栈信息
     *
     * @param t
     * @return
     */
    public  String getInfo(Throwable t) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        try {
            t.printStackTrace(pw);
            return sw.toString();
        } finally {
            pw.close();
        }
    }
}