From 2bf9de54501a11acc321168c869b8a70f8fc78a0 Mon Sep 17 00:00:00 2001 From: weicw <594098497@qq.com> Date: Mon, 26 Oct 2026 13:48:32 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20Feign=20=E9=99=8D=E7=BA=A7=E5=93=8D?= =?UTF-8?q?=E5=BA=94=E6=97=A0=E6=B3=95=E6=8C=89=E8=BF=94=E5=9B=9E=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=8F=8D=E5=BA=8F=E5=88=97=E5=8C=96=E6=97=B6=E9=99=8D?= =?UTF-8?q?=E7=BA=A7=E4=B8=BA=E5=A4=B1=E8=B4=A5=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 服务端把 data:null 序列化成 {},客户端泛型为 Boolean 等标量时 convertValue 抛异常,被 BladeSentinelInvocationHandler 包成 AssertionError(Error 而非 Exception),击穿调用方的 catch (Exception),把可恢复的 4xx 升级成 500。 改为记 WARN 并返回 R.fail,保留服务端 code/msg。 --- .../core/cloud/feign/BladeFeignFallback.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/blade-core-cloud/src/main/java/org/springblade/core/cloud/feign/BladeFeignFallback.java b/blade-core-cloud/src/main/java/org/springblade/core/cloud/feign/BladeFeignFallback.java index 24e630b..3f6e72b 100644 --- a/blade-core-cloud/src/main/java/org/springblade/core/cloud/feign/BladeFeignFallback.java +++ b/blade-core-cloud/src/main/java/org/springblade/core/cloud/feign/BladeFeignFallback.java @@ -106,7 +106,16 @@ public class BladeFeignFallback implements MethodInterceptor { if (resultNode.has(CODE)) { // 支持 R 及其子类(如 FR)的泛型反序列化,保留服务端失败原因 JavaType javaType = JsonUtil.getInstance().getTypeFactory().constructType(method.getGenericReturnType()); - return JsonUtil.getInstance().convertValue(resultNode, javaType); + try { + return JsonUtil.getInstance().convertValue(resultNode, javaType); + } catch (Exception convertException) { + // 服务端 data 被写成 {}(null 空值序列化)而客户端泛型是 Boolean 这类标量时无法反序列化。 + // 此处抛出会被 BladeSentinelInvocationHandler 包成 AssertionError(Error 而非 Exception), + // 击穿调用方的 catch (Exception),把可恢复的 4xx 升级成 500,故一律降级为失败结果。 + log.warn("BladeFeignFallback:[{}.{}] 响应体无法按 {} 反序列化,降级为失败结果:{}", + targetType.getName(), method.getName(), method.getGenericReturnType(), convertException.getMessage()); + return R.fail(resultNode.path(CODE).asInt(ResultCode.FAILURE.getCode()), resultNode.path("msg").asText(errorMessage)); + } } return R.fail(resultNode.toString()); }