Skip to content

Commit f26f50b

Browse files
committed
feat: 添加网关全局异常处理器
1 parent 7faf8f0 commit f26f50b

5 files changed

Lines changed: 92 additions & 10 deletions

File tree

framework/framework_api/src/main/java/com/github/cadecode/uniboot/framework/api/enums/FrameErrorEnum.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,18 @@ public int getStatus() {
5858
UPLOAD_FILE_FAIL(2002, "上传文件失败"),
5959
FILE_NOT_FOUND(2003, "文件未找到"),
6060

61-
// rpc
62-
RPC_UNKNOWN_ERROR(3001, "RPC UNKNOWN 异常"),
63-
RPC_UNWRAP_FAIL(3002, "RPC UNWRAP 失败"),
61+
// cloud
62+
RPC_UNKNOWN_ERROR(3001, "[RPC]UNKNOWN 异常"),
63+
RPC_UNWRAP_FAIL(3002, "[RPC]UNWRAP 失败"),
64+
GW_SVC_NOT_FOUND(3003, "[GW]服务未找到") {
65+
@Override
66+
public int getStatus() {
67+
return ApiStatus.SERVER_UNAVAILABLE;
68+
}
69+
},
70+
GW_RES_STATUS_ERROR(3004, "[GW]响应状态错误"),
71+
GW_SVC_INTERNAL_ERROR(3005, "[GW]服务内部错误"),
72+
6473
;
6574

6675
private final String code;

framework/framework_base/src/main/java/com/github/cadecode/uniboot/framework/base/feign/FeignErrorDecoder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public Exception decode(String methodKey, Response response) {
4848
// 构造 ApiErrorCode
4949
ApiErrorCode errorCode = getErrorCode(result, error);
5050
// 构造 moreInfo
51-
String moreInfo = getMoreInfo(error);
51+
String moreInfo = markMoreInfo(error);
5252
return ApiException.of(errorCode, moreInfo);
5353
}
5454

@@ -75,9 +75,9 @@ public int getStatus() {
7575
}
7676

7777
/**
78-
* 根据 ErrorMessage 获取 moreInfo 字符串
78+
* 获取 moreInfo 字符串,在前面加上 RPC 标记
7979
*/
80-
private String getMoreInfo(ErrorMessage error) {
80+
private String markMoreInfo(ErrorMessage error) {
8181
String moreInfo = error.getMoreInfo();
8282
// 在 moreInfo 前段追加 RPC 标记
8383
if (!StrUtil.startWith(moreInfo, "[RPC]")) {

gateway/pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,6 @@
7878
<groupId>com.github.cadecode</groupId>
7979
<artifactId>uni-boot-framework-api</artifactId>
8080
<exclusions>
81-
<exclusion>
82-
<groupId>com.github.cadecode</groupId>
83-
<artifactId>uni-boot-common-core</artifactId>
84-
</exclusion>
8581
<exclusion>
8682
<groupId>com.github.cadecode</groupId>
8783
<artifactId>uni-boot-common-plugin-cache</artifactId>
@@ -90,6 +86,10 @@
9086
<groupId>com.github.cadecode</groupId>
9187
<artifactId>uni-boot-common-plugin-log</artifactId>
9288
</exclusion>
89+
<exclusion>
90+
<groupId>org.springframework.boot</groupId>
91+
<artifactId>spring-boot-starter-web</artifactId>
92+
</exclusion>
9393
</exclusions>
9494
</dependency>
9595
<dependency>

gateway/src/main/java/com/github/cadecode/uniboot/gateway/UniGatewayApplication.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
package com.github.cadecode.uniboot.gateway;
22

3+
import com.github.cadecode.uniboot.common.core.extension.strategy.StrategyService;
34
import org.springframework.boot.SpringApplication;
45
import org.springframework.boot.autoconfigure.SpringBootApplication;
56
import org.springframework.boot.builder.SpringApplicationBuilder;
67
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
78
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
89
import org.springframework.cloud.openfeign.EnableFeignClients;
910
import org.springframework.context.annotation.EnableAspectJAutoProxy;
11+
import org.springframework.plugin.core.config.EnablePluginRegistries;
1012

1113
/**
1214
* 启动类
1315
*/
16+
@EnablePluginRegistries({StrategyService.class})
1417
@EnableFeignClients("com.github.cadecode")
1518
@EnableDiscoveryClient
1619
@EnableAspectJAutoProxy(exposeProxy = true)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.github.cadecode.uniboot.gateway.handler;
2+
3+
import cn.hutool.core.util.ObjectUtil;
4+
import com.github.cadecode.uniboot.common.core.enums.ApiErrorCode;
5+
import com.github.cadecode.uniboot.common.core.util.JacksonUtil;
6+
import com.github.cadecode.uniboot.common.core.web.response.ApiResult;
7+
import com.github.cadecode.uniboot.framework.api.enums.FrameErrorEnum;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
10+
import org.springframework.cloud.gateway.support.NotFoundException;
11+
import org.springframework.core.annotation.Order;
12+
import org.springframework.core.io.buffer.DataBuffer;
13+
import org.springframework.http.HttpHeaders;
14+
import org.springframework.http.HttpStatus;
15+
import org.springframework.http.MediaType;
16+
import org.springframework.http.server.reactive.ServerHttpResponse;
17+
import org.springframework.stereotype.Component;
18+
import org.springframework.web.server.ResponseStatusException;
19+
import org.springframework.web.server.ServerWebExchange;
20+
import reactor.core.publisher.Mono;
21+
22+
/**
23+
* 网关全局异常处理
24+
*
25+
* @author Cade Li
26+
* @since 2023/8/11
27+
*/
28+
@Slf4j
29+
@Order(-1)
30+
@Component
31+
public class GlobalExceptionHandler implements ErrorWebExceptionHandler {
32+
33+
@Override
34+
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
35+
ServerHttpResponse response = exchange.getResponse();
36+
if (exchange.getResponse().isCommitted()) {
37+
return Mono.error(ex);
38+
}
39+
ApiResult<Object> result = getApiResultFromEx(exchange, ex);
40+
log.error("[GW]Exception handler=> status:{}, path:{}, msg:{},", result.getStatus(), result.getError().getPath(), result.getError().getMessage(), ex);
41+
response.setStatusCode(HttpStatus.resolve(result.getStatus()));
42+
response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
43+
DataBuffer dataBuffer = response.bufferFactory().wrap(JacksonUtil.toJson(result).getBytes());
44+
return response.writeWith(Mono.just(dataBuffer));
45+
}
46+
47+
private ApiResult<Object> getApiResultFromEx(ServerWebExchange exchange, Throwable ex) {
48+
String moreInfo = ex.getMessage();
49+
String path = exchange.getRequest().getPath().toString();
50+
Integer status = null;
51+
ApiErrorCode errorCode;
52+
// 服务未找到 503
53+
if (ex instanceof NotFoundException) {
54+
errorCode = FrameErrorEnum.GW_SVC_NOT_FOUND;
55+
} else if (ex instanceof ResponseStatusException) {
56+
// 响应状态异常
57+
errorCode = FrameErrorEnum.GW_RES_STATUS_ERROR;
58+
ResponseStatusException e = (ResponseStatusException) ex;
59+
status = e.getStatus().value();
60+
} else {
61+
// 其他异常
62+
errorCode = FrameErrorEnum.GW_SVC_INTERNAL_ERROR;
63+
}
64+
ApiResult<Object> result = ApiResult.error(errorCode).moreInfo(moreInfo).path(path);
65+
if (ObjectUtil.isNotNull(status)) {
66+
result.status(status);
67+
}
68+
return result;
69+
}
70+
}

0 commit comments

Comments
 (0)