fegin报错传递

This commit is contained in:
litianxiang
2026-05-20 17:19:15 +08:00
parent b6e4dc9673
commit 3e9fc95659
5 changed files with 102 additions and 8 deletions

View File

@@ -26,7 +26,7 @@ public class BuyerAccountController {
}
@PostMapping("/register")
@Operation(summary = "注册")
@Operation(summary = "获取验证码后注册")
public Boolean register(@Valid @RequestBody RegisterDTO dto) {
return buyerAccountService.register(dto);
}

View File

@@ -1,12 +1,14 @@
package com.aida.buyer.module.feign.config;
import com.aida.buyer.module.feign.decoder.BusinessErrorFeignDecoder;
import com.aida.buyer.module.feign.interceptor.InternalCallInterceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.RequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Feign 全局配置:注册所有 Feign 拦截器。
* Feign 全局配置:注册所有 Feign 拦截器和 Decoder
*/
@Configuration
public class FeignConfig {
@@ -15,4 +17,9 @@ public class FeignConfig {
public RequestInterceptor internalCallInterceptor() {
return new InternalCallInterceptor();
}
@Bean
public BusinessErrorFeignDecoder businessErrorFeignDecoder(ObjectMapper objectMapper) {
return new BusinessErrorFeignDecoder(objectMapper);
}
}

View File

@@ -0,0 +1,92 @@
package com.aida.buyer.module.feign.decoder;
import com.aida.buyer.common.exception.BusinessException;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.FeignException;
import feign.Request;
import feign.Response;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import lombok.RequiredArgsConstructor;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Map;
/**
* Feign 全局 Decoder。
*
* <p>背景seller 端使用 {@code @RestControllerAdvice} 将 {@code BusinessException}
* 转为 HTTP 200 + {@code Response.fail(code, msg)} 返回。
* 默认 Decoder 只看 HTTP 状态码2xx 一律视为成功,导致 buyer 端无法感知远程业务错误。</p>
*
* <p>本 Decoder 在解析响应体时:
* <ul>
* <li>若 HTTP 状态码为 2xx先将 body 读取为字符串并解析为标准 {@code Response}</li>
* <li>若 {@code errCode != 0},抛出 {@link BusinessException},错误信息为远程返回的 errMsg</li>
* <li>否则使用 {@link ObjectMapper} 将 body 反序列化为目标类型 {@code T}。</li>
* </ul>
* </p>
*
* <p>HTTP 非 2xx 状态码(如 500、服务不可用由 Feign 默认 ErrorDecoder 抛出
* {@link FeignException},不在本 Decoder 处理范围内。</p>
*/
@RequiredArgsConstructor
public class BusinessErrorFeignDecoder implements Decoder {
private final ObjectMapper objectMapper;
@Override
@SuppressWarnings("unchecked")
public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
if (!is2xx(response.status())) {
throw FeignException.errorStatus(requestKey(response), response);
}
String body = readBody(response);
if (body == null || body.isBlank()) {
return null;
}
// 先按标准 Response 格式解析,校验 errCode
com.aida.buyer.common.result.Response<?> genericResp = objectMapper.readValue(body, com.aida.buyer.common.result.Response.class);
if (genericResp.getErrCode() != 0) {
throw new BusinessException(
genericResp.getErrCode(),
genericResp.getErrMsg() != null ? genericResp.getErrMsg() : "远程服务业务错误"
);
}
// errCode == 0ObjectMapper 反序列化为目标类型
return objectMapper.readValue(body, objectMapper.getTypeFactory().constructType(type));
}
private boolean is2xx(int status) {
return status >= 200 && status < 300;
}
private String readBody(Response response) throws IOException {
if (response.body() == null) {
return null;
}
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(response.body().asInputStream(), StandardCharsets.UTF_8))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
return sb.toString();
}
}
private String requestKey(Response response) {
Request request = response.request();
return request.method() + " " + request.url();
}
}

View File

@@ -1,7 +1,6 @@
package com.aida.buyer.module.order.service.impl;
import com.aida.buyer.common.context.UserContext;
import com.aida.buyer.common.exception.BusinessException;
import com.aida.buyer.common.result.PageResponse;
import com.aida.buyer.common.result.Response;
import com.aida.buyer.module.account.entity.BuyerAccount;
@@ -46,10 +45,6 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
dto.setBuyerUsername(account.getUsername());
Response<CreateOrderResultVO> orderResp = orderFeignClient.createOrder(dto);
if (orderResp == null || orderResp.getErrCode() != 0) {
throw new BusinessException("创建订单失败");
}
CreateOrderResultVO result = orderResp.getData();
// TODO:调用支付模块传入buyerIdresult.getOrderIds()result.getTotalAmount()

View File

@@ -4,7 +4,7 @@
# ============================================================
nacos:
namespace: ltx
namespace: dev
host: 18.167.251.121:28848
username: nacos
password: Aidlab123123!