【发布时间】:2020-10-21 04:58:45
【问题描述】:
我的代码故意抛出 SourceAssertionError。在早前的 5.1.6.release 中,对于任何错误,在 RequestHandlerRetryAdvice 中,对于任何错误,它都会将其包装在 MessagingException 中。在RequestHandlerRetryAdvice的doInvoke()下面,
@Override
protected Object doInvoke(final ExecutionCallback callback, Object target, final Message<?> message)
throws Exception {
RetryState retryState = null;
retryState = this.retryStateGenerator.determineRetryState(message);
messageHolder.set(message);
try {
return this.retryTemplate.execute(context -> callback.cloneAndExecute(), this.recoveryCallback, retryState);
}
catch (MessagingException e) {
if (e.getFailedMessage() == null) {
throw new MessagingException(message, "Failed to invoke handler", e);
}
throw e;
}
catch (Exception e) {
throw new MessagingException(message, "Failed to invoke handler", unwrapExceptionIfNecessary(e));
}
finally {
messageHolder.remove();
}
}
但现在在 5.3.2.Release 中,它没有包含在 MEssagingException 中,而是作为 THrowableHolderException 抛出,如下所示
@Override
protected Object doInvoke(final ExecutionCallback callback, Object target, final Message<?> message) {
RetryState retryState = this.retryStateGenerator.determineRetryState(message);
MESSAGE_HOLDER.set(message);
try {
return this.retryTemplate.execute(context -> callback.cloneAndExecute(), this.recoveryCallback, retryState);
}
catch (MessagingException e) {
if (e.getFailedMessage() == null) {
throw new MessagingException(message, "Failed to invoke handler", e);
}
throw e;
}
catch (ThrowableHolderException e) { // NOSONAR catch and rethrow
throw e;
}
catch (Exception e) {
throw new ThrowableHolderException(e);
}
finally {
MESSAGE_HOLDER.remove();
}
}
现在,在 spring-integration 升级之后,我的代码流以这样一种方式进行,即错误(Not MessagingException)没有被路由到错误通道。 RequestRetryHandlerAdvice 中的 doInvoke() 抛出的异常在路由到错误通道之前被拒绝,因为逻辑要求它们是特定类型的,即,如果只有异常是 MessaginException,则将其路由到错误通道。流程退出,但 GatewayProxyFactoryBean 中的 rethrowExceptionCauseIfPossible(..) 抛出异常。在升级之前,我的错误已被包装到 MessagingException 并且流程到达 MessagingGatewaySupport 中的 handleSendAndReceiveError(..),它通常被路由到自定义定义的错误通道。升级到 5.3.2 后不会发生这种情况。随着流程在其自身之前结束而发布
我的 spring 配置非常简单,我只为网关定义了一个自定义错误通道。
现在我的问题是如何处理这个错误?无论如何我可以通过路由到任何新定义的错误通道来处理它,或者我可以对我已经定义的 myErrorChannel 进行处理吗? EDIT1:根据 Artem Bilan 请求添加配置文件 而我的 Transformer 被定义为 <bean id="myPreferences" class="package.MyPreferences" />
<bean id="myExceptionTransformer"
class="package.myExceptionTransformer" />
<int:channel id="myErrorChannel" />
<int:transformer input-channel="myErrorChannel"
ref="myExceptionTransformer" />
<bean id="Logger" class="package.Logger" />
<int:gateway id="gateway" error-channel="myErrorChannel"
service-interface="package.myClient"
default-request-channel="myRoutingChannel">
<int:method name="invokeAuthenticationRequest">
<int:header
name="#{T(name1)}"
value="#{T(value1)}" />
</int:method>
<int:method name="invokeProvRequest">
<int:header
name="#{T(name2)}"
value="#{T(value2)}" />
</int:method>
</int:gateway>
<int:publish-subscribe-channel id="myRoutingChannel" />
<int:header-value-router input-channel="myRoutingChannel"
header-name="#{T(package.AppContext).REQUEST_TYPE}">
<int:mapping
value="#{T(value1)}"
channel="authGatewayChannel" />
<int:mapping
value="#{T(value2)}"
channel="provGatewayChannel" />
</int:header-value-router>
<int-ws:request-handler-advice-chain>
<ref bean="provRetryAdvice" />
</int-ws:request-handler-advice-chain>
</int-ws:outbound-gateway>
<bean id="provRetryAdvice"
class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
<property name="retryTemplate">
<bean class="org.springframework.retry.support.RetryTemplate">
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.FixedBackOffPolicy">
<property name="backOffPeriod" value="4000" />
</bean>
</property>
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="#{provisioningRetryCount.intValue()}" />
</bean>
</property>
</bean>
</property>
</bean>
@Transformer
public Message<?> transformErrorToResponse(Message<?> exceptionMessage) {
Object exceptionMessagePayload = exceptionMessage.getPayload();
Throwable cause = ((MessagingException) exceptionMessagePayload).getCause();
newPayload = new myException(msg);
/*add headers*/
return errorMessage;
}
【问题讨论】:
-
添加了错误通道的配置和转换器
标签: java exception error-handling spring-integration