You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

enricher子流中Http.outboundGateway异常暴露及404自定义处理问题

URL配置错误被吞问题排查与解决方案

问题描述

遇到URL配置错误引发的异常被吞问题,初始配置代码如下:

@Bean
ExpressionEvaluatingRequestHandlerAdvice notFoundAdvice() {
    final ExpressionEvaluatingRequestHandlerAdvice advice =
        new ExpressionEvaluatingRequestHandlerAdvice();
    advice.setOnFailureExpressionString(
        "#exception.getCause()"
        + " instanceof T(org.springframework.web.client.HttpClientErrorException.NotFound)"
        + " ? '{ \"value\": null }' : payload"
    );
    advice.setReturnFailureExpressionResult(true);
    return advice;
}

@Bean
public IntegrationFlow myIntegrationFlow(final RestTemplate restTemplate) {
    return f -> f
        .enrich(
            e -> e.requestSubFlow(
                sf -> sf
                    .handle(
                        Http.outboundGateway(misconfiguredUrl, restTemplate)
                            .httpMethod(HttpMethod.GET)
                            .uriVariable("productId", "headers.productId")
                            .mappedResponseHeaders()
                            .expectedResponseType(String.class),
                        ec -> ec.advice(notFoundAdvice())
                    )
                )
                .propertyExpression("productData", "#jsonPath(payload, '$.value')")
            )
        );
}

问题现象:当misconfiguredUrl未包含http://host前缀时,会触发URL格式错误,但运行时没有直接抛出该错误,反而出现#jsonPath(...)报错提示$[value]不存在。

排查过程

  1. 初步排查发现两个问题:
    • 遗漏了处理合法404错误的端点配置
    • 错误配置了setReturnFailureExpressionResult参数,移除该配置后异常可以正常暴露
  2. 后续测试发现该方案不完善,虽然异常能暴露,但无法实现仅捕获404异常返回默认值、其他异常正常抛出的需求,需要调整实现思路
  3. 最终实现自定义处理类解决问题,代码如下:
public class CustomNotFoundAdvice extends AbstractRequestHandlerAdvice {
    private static final Logger log = LoggerFactory.getLogger(CustomNotFoundAdvice.class);

    final Object defaultReturn;

    public CustomNotFoundAdvice(final Object defaultReturn) {
        this.defaultReturn = defaultReturn;
    }

    @Override
    protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) {
        Object result;
        try {
            result = callback.execute();
        }
        catch(RuntimeException ex) {
            final Exception realException = unwrapExceptionIfNecessary(ex);
            if( realException instanceof MessageHandlingException
                    && realException.getCause() instanceof HttpClientErrorException.NotFound) {
                log.warn("Unable to locate object "+target);
                result = defaultReturn;
            }
            else {
                throw ex;
            }
        }
        return result;
    }
    
}

方案说明

最终实现的自定义Advice是最优解决方案,既满足了仅对404异常返回默认值的业务需求,又不会吞掉其他异常,所有非404异常都会正常向上抛出,默认会被日志框架捕获打印,无需额外配置。如果需要更精细化的日志记录,可在自定义类的else分支抛出异常前添加对应的日志打印逻辑即可。

内容的提问来源于stack exchange,提问作者Dave G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 23:57:03