dongyukun
2024-12-16 0f60af4728662e076ab04a2d352eed6286f294be
提交 | 用户 | 时间
e7c126 1 package com.iailab.gateway.handler;
H 2
3 import com.iailab.framework.common.pojo.CommonResult;
4 import com.iailab.gateway.util.WebFrameworkUtils;
5 import lombok.extern.slf4j.Slf4j;
6 import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
7 import org.springframework.core.annotation.Order;
8 import org.springframework.http.server.reactive.ServerHttpRequest;
9 import org.springframework.http.server.reactive.ServerHttpResponse;
10 import org.springframework.stereotype.Component;
11 import org.springframework.web.bind.annotation.ExceptionHandler;
12 import org.springframework.web.server.ResponseStatusException;
13 import org.springframework.web.server.ServerWebExchange;
14 import reactor.core.publisher.Mono;
15
16 import static com.iailab.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
17
18 /**
19  * Gateway 的全局异常处理器,将 Exception 翻译成 CommonResult + 对应的异常编号
20  *
21  * 在功能上,和 iailab-common-web 的 GlobalExceptionHandler 类是一致的
22  *
23  * @author iailab
24  */
25 @Component
26 @Order(-1) // 保证优先级高于默认的 Spring Cloud Gateway 的 ErrorWebExceptionHandler 实现
27 @Slf4j
28 public class GlobalExceptionHandler implements ErrorWebExceptionHandler {
29
30     @Override
31     public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
32         // 已经 commit,则直接返回异常
33         ServerHttpResponse response = exchange.getResponse();
34         if (response.isCommitted()) {
35             return Mono.error(ex);
36         }
37
38         // 转换成 CommonResult
39         CommonResult<?> result;
40         if (ex instanceof ResponseStatusException) {
41             result = responseStatusExceptionHandler(exchange, (ResponseStatusException) ex);
42         } else {
43             result = defaultExceptionHandler(exchange, ex);
44         }
45
46         // 返回给前端
47         return WebFrameworkUtils.writeJSON(exchange, result);
48     }
49
50     /**
51      * 处理 Spring Cloud Gateway 默认抛出的 ResponseStatusException 异常
52      */
53     private CommonResult<?> responseStatusExceptionHandler(ServerWebExchange exchange,
54                                                            ResponseStatusException ex) {
55         // TODO iailab:这里要精细化翻译,默认返回用户是看不懂的
56         ServerHttpRequest request = exchange.getRequest();
57         log.error("[responseStatusExceptionHandler][uri({}/{}) 发生异常]", request.getURI(), request.getMethod(), ex);
58         return CommonResult.error(ex.getRawStatusCode(), ex.getReason());
59     }
60
61     /**
62      * 处理系统异常,兜底处理所有的一切
63      */
64     @ExceptionHandler(value = Exception.class)
65     public CommonResult<?> defaultExceptionHandler(ServerWebExchange exchange,
66                                                    Throwable ex) {
67         ServerHttpRequest request = exchange.getRequest();
68         log.error("[defaultExceptionHandler][uri({}/{}) 发生异常]", request.getURI(), request.getMethod(), ex);
69         // TODO iailab:是否要插入异常日志呢?
70         // 返回 ERROR CommonResult
71         return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
72     }
73
74 }