如果在spring-integration的webflux流中发生异常,则异常本身(带有stacktrace)将通过MessagePublishingErrorHandler作为有效负载发送回调用方,后者使用来自“ errorChannel”标头的错误通道,而不是默认错误通道。

如何设置类似于WebExceptionHandler的错误处理程序?我想生成一个Http状态代码,并可能生成一个DefaultErrorAttributes对象作为响应。

简单地定义从errorChannel开始的流是行不通的,错误消息不会在那里结束。我尝试定义自己的fluxErrorChannel,但它似乎也没有用作错误通道,错误并没有出现在我的errorFlow中:

@Bean
public IntegrationFlow fooRestFlow() {
    return IntegrationFlows.from(
            WebFlux.inboundGateway("/foo")
                    .requestMapping(r -> r.methods(HttpMethod.POST))
                    .requestPayloadType(Map.class)
                    .errorChannel(fluxErrorChannel()))
            .channel(bazFlow().getInputChannel())
            .get();
}

@Bean
public MessageChannel fluxErrorChannel() {
    return MessageChannels.flux().get();
}

@Bean
public IntegrationFlow errorFlow() {
    return IntegrationFlows.from(fluxErrorChannel())
            .transform(source -> source)
            .enrichHeaders(h -> h.header(HttpHeaders.STATUS_CODE, HttpStatus.BAD_GATEWAY))
            .get();
}

@Bean
public IntegrationFlow bazFlow() {
    return f -> f.split(Map.class, map -> map.get("items"))
            .channel(MessageChannels.flux())
            .<String>handle((p, h) -> throw new RuntimeException())
            .aggregate();
}


更新

MessagingGatewaySupport.doSendAndReceiveMessageReactive中,我从未在WebFlux.inboundGateway上定义的错误通道用于设置错误通道,而是错误通道始终是正在创建的replyChannel here

FutureReplyChannel replyChannel = new FutureReplyChannel();

Message<?> requestMessage = MutableMessageBuilder.fromMessage(message)
    .setReplyChannel(replyChannel)
    .setHeader(this.messagingTemplate.getSendTimeoutHeader(), null)
    .setHeader(this.messagingTemplate.getReceiveTimeoutHeader(), null)
    .setErrorChannel(replyChannel)
    .build();


错误通道最终将被重置为originalErrorChannelHandler中的Mono.fromFuture,但是在我的情况下,该错误通道为“ null”。另外,永远不会调用onErrorResume lambda:

return Mono.fromFuture(replyChannel.messageFuture)
    .doOnSubscribe(s -> {
        if (!error && this.countsEnabled) {
            this.messageCount.incrementAndGet();
        }
    })
    .<Message<?>>map(replyMessage ->
        MessageBuilder.fromMessage(replyMessage)
            .setHeader(MessageHeaders.REPLY_CHANNEL, originalReplyChannelHeader)
            .setHeader(MessageHeaders.ERROR_CHANNEL, originalErrorChannelHeader)
            .build())
    .onErrorResume(t -> error ? Mono.error(t) : handleSendError(requestMessage, t));


这打算如何运作?

最佳答案

这是一个错误;由错误处理程序为异常创建的ErrorMessage被发送到errorChannel标头(必须为replyChannel,以便网关获取结果)。然后,网关应调用错误流(如果存在)并返回错误结果。

https://jira.spring.io/browse/INT-4541

10-06 10:01