/** * Specify a {@link MessageChannel} to use for sending error message in case * of polling failures. * @param errorChannel the {@link MessageChannel} to use. * @return the spec. * @see MessagePublishingErrorHandler */ public PollerSpec errorChannel(MessageChannel errorChannel) { MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler(); errorHandler.setDefaultErrorChannel(errorChannel); this.componentsToRegister.put(errorHandler, null); return errorHandler(errorHandler); }
/** * Specify a bean name for the {@link MessageChannel} to use for sending error message in case * of polling failures. * @param errorChannelName the bean name for {@link MessageChannel} to use. * @return the spec. * @see MessagePublishingErrorHandler */ public PollerSpec errorChannel(String errorChannelName) { MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler(); errorHandler.setDefaultErrorChannelName(errorChannelName); this.componentsToRegister.put(errorHandler, null); return errorHandler(errorHandler); }
@Override public final void handleError(Throwable t) { MessageChannel errorChannel = resolveErrorChannel(t); boolean sent = false; if (errorChannel != null) { try { getMessagingTemplate().send(errorChannel, getErrorMessageStrategy().buildErrorMessage(t, null)); sent = true; } catch (Throwable errorDeliveryError) { //NOSONAR // message will be logged only if (this.logger.isWarnEnabled()) { this.logger.warn("Error message was not delivered.", errorDeliveryError); } if (errorDeliveryError instanceof Error) { throw ((Error) errorDeliveryError); } } } if (!sent && this.logger.isErrorEnabled()) { Message<?> failedMessage = (t instanceof MessagingException) ? ((MessagingException) t).getFailedMessage() : null; if (failedMessage != null) { this.logger.error("failure occurred in messaging task with message: " + failedMessage, t); } else { this.logger.error("failure occurred in messaging task", t); } } }
@Nullable private MessageChannel resolveErrorChannel(Throwable t) { Throwable actualThrowable = t; if (t instanceof MessagingExceptionWrapper) { actualThrowable = t.getCause(); } Message<?> failedMessage = (actualThrowable instanceof MessagingException) ? ((MessagingException) actualThrowable).getFailedMessage() : null; if (getDefaultErrorChannel() == null && getChannelResolver() != null) { setChannel(getChannelResolver().resolveDestination(// NOSONAR not null IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)); } if (failedMessage == null || failedMessage.getHeaders().getErrorChannel() == null) { return getDefaultErrorChannel(); } Object errorChannelHeader = failedMessage.getHeaders().getErrorChannel(); if (errorChannelHeader instanceof MessageChannel) { return (MessageChannel) errorChannelHeader; } Assert.isInstanceOf(String.class, errorChannelHeader, () -> "Unsupported error channel header type. Expected MessageChannel or String, but actual type is [" + errorChannelHeader.getClass() + "]"); // NOSONAR never null here if (getChannelResolver() != null) { return getChannelResolver().resolveDestination((String) errorChannelHeader); // NOSONAR not null } else { return null; } }
@Override protected void onInit() { super.onInit(); if (this.errorHandler == null) { Assert.notNull(getBeanFactory(), "BeanFactory is required"); this.errorHandler = new MessagePublishingErrorHandler(new BeanFactoryChannelResolver(getBeanFactory())); } }
MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler(); errorHandler.setDefaultErrorChannelName(errorChannel); errorHandler.setBeanFactory(this.beanFactory); pollerMetadata.setErrorHandler(errorHandler);
@Test public void defaultErrorChannelAndHandlerThrowsExceptionWithDelay() { this.delayHandler.setRetryDelay(1); StaticApplicationContext context = new StaticApplicationContext(); context.registerSingleton(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME, DirectChannel.class); context.refresh(); DirectChannel defaultErrorChannel = (DirectChannel) context .getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME); MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler(); errorHandler.setBeanFactory(context); taskScheduler.setErrorHandler(errorHandler); this.setDelayExpression(); startDelayerHandler(); output.unsubscribe(resultHandler); defaultErrorChannel.subscribe(resultHandler); output.subscribe(message -> { throw new UnsupportedOperationException("intentional test failure"); }); Message<?> message = MessageBuilder.withPayload("test") .setHeader("delay", "10").build(); input.send(message); waitForLatch(10000); Message<?> errorMessage = resultHandler.lastMessage; assertEquals(MessageDeliveryException.class, errorMessage.getPayload().getClass()); MessageDeliveryException exceptionPayload = (MessageDeliveryException) errorMessage.getPayload(); assertSame(message.getPayload(), exceptionPayload.getFailedMessage().getPayload()); assertEquals(UnsupportedOperationException.class, exceptionPayload.getCause().getClass()); assertNotSame(Thread.currentThread(), resultHandler.lastThread); }
public final void handle(Throwable t) { Message<?> failedMessage = (t instanceof MessagingException) ? ((MessagingException) t).getFailedMessage() : null; MessageChannel errorChannel = this.resolveErrorChannel(failedMessage); boolean sent = false; if (errorChannel != null) { try { if (this.sendTimeout >= 0) { sent = errorChannel.send(new ErrorMessage(t), this.sendTimeout); } else { sent = errorChannel.send(new ErrorMessage(t)); } } catch (Throwable errorDeliveryError) { // message will be logged only if (logger.isWarnEnabled()) { logger.warn("Error message was not delivered.", errorDeliveryError); } } } if (!sent && logger.isErrorEnabled()) { if (failedMessage != null) { logger.error("failure occurred in messaging task with message: " + failedMessage, t); } else { logger.error("failure occurred in messaging task", t); } } }
/** * Return the default error channel for this error handler. * @return the error channel. * @since 4.3 */ @Nullable public MessageChannel getDefaultErrorChannel() { return getChannel(); }
if (this.errorHandler == null) { Assert.notNull(this.getBeanFactory(), "BeanFactory is required"); this.errorHandler = new MessagePublishingErrorHandler( new BeanFactoryChannelResolver(getBeanFactory())); this.errorHandlerIsDefault = true;
MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler(); errorHandler.setDefaultErrorChannelName(errorChannel); errorHandler.setBeanFactory(this.beanFactory); pollerMetadata.setErrorHandler(errorHandler);
context.refresh(); DirectChannel customErrorChannel = (DirectChannel) context.getBean(errorChannelName); MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler(); errorHandler.setBeanFactory(context); taskScheduler.setErrorHandler(errorHandler); this.setDelayExpression();
@Nullable private MessageChannel resolveErrorChannel(Throwable t) { Throwable actualThrowable = t; if (t instanceof MessagingExceptionWrapper) { actualThrowable = t.getCause(); } Message<?> failedMessage = (actualThrowable instanceof MessagingException) ? ((MessagingException) actualThrowable).getFailedMessage() : null; if (getDefaultErrorChannel() == null && getChannelResolver() != null) { setChannel(getChannelResolver().resolveDestination(// NOSONAR not null IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)); } if (failedMessage == null || failedMessage.getHeaders().getErrorChannel() == null) { return getDefaultErrorChannel(); } Object errorChannelHeader = failedMessage.getHeaders().getErrorChannel(); if (errorChannelHeader instanceof MessageChannel) { return (MessageChannel) errorChannelHeader; } Assert.isInstanceOf(String.class, errorChannelHeader, () -> "Unsupported error channel header type. Expected MessageChannel or String, but actual type is [" + errorChannelHeader.getClass() + "]"); // NOSONAR never null here if (getChannelResolver() != null) { return getChannelResolver().resolveDestination((String) errorChannelHeader); // NOSONAR not null } else { return null; } }
/** * Return the default error channel for this error handler. * @return the error channel. * @since 4.3 */ @Nullable public MessageChannel getDefaultErrorChannel() { return getChannel(); }
@Override protected void onInit() { super.onInit(); if (this.expectMessage) { Assert.notNull(this.serializer, "'serializer' has to be provided where 'expectMessage == true'."); } if (this.taskExecutor == null) { String beanName = this.getComponentName(); this.taskExecutor = new SimpleAsyncTaskExecutor((beanName == null ? "" : beanName + "-") + this.getComponentType()); } if (!(this.taskExecutor instanceof ErrorHandlingTaskExecutor) && this.getBeanFactory() != null) { MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler(new BeanFactoryChannelResolver(this.getBeanFactory())); errorHandler.setDefaultErrorChannel(this.errorChannel); this.taskExecutor = new ErrorHandlingTaskExecutor(this.taskExecutor, errorHandler); } }
@Override public final void onInit() { Assert.state(getDispatcher().getHandlerCount() == 0, "You cannot subscribe() until the channel " + "bean is fully initialized by the framework. Do not subscribe in a @Bean definition"); super.onInit(); if (!(this.executor instanceof ErrorHandlingTaskExecutor)) { ErrorHandler errorHandler = new MessagePublishingErrorHandler( new BeanFactoryChannelResolver(this.getBeanFactory())); this.executor = new ErrorHandlingTaskExecutor(this.executor, errorHandler); } UnicastingDispatcher unicastingDispatcher = new UnicastingDispatcher(this.executor); unicastingDispatcher.setFailover(this.failover); if (this.maxSubscribers == null) { this.maxSubscribers = getIntegrationProperty(IntegrationProperties.CHANNELS_MAX_UNICAST_SUBSCRIBERS, Integer.class); } unicastingDispatcher.setMaxSubscribers(this.maxSubscribers); if (this.loadBalancingStrategy != null) { unicastingDispatcher.setLoadBalancingStrategy(this.loadBalancingStrategy); } unicastingDispatcher.setMessageHandlingTaskDecorator(task -> { if (ExecutorChannel.this.executorInterceptorsSize > 0) { return new MessageHandlingTask(task); } else { return task; } }); this.dispatcher = unicastingDispatcher; }
/** * Specify a bean name for the {@link MessageChannel} to use for sending error message in case * of polling failures. * @param errorChannelName the bean name for {@link MessageChannel} to use. * @return the spec. * @see MessagePublishingErrorHandler */ public PollerSpec errorChannel(String errorChannelName) { MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler(); errorHandler.setDefaultErrorChannelName(errorChannelName); this.componentsToRegister.put(errorHandler, null); return errorHandler(errorHandler); }
@Override public final void handleError(Throwable t) { MessageChannel errorChannel = resolveErrorChannel(t); boolean sent = false; if (errorChannel != null) { try { getMessagingTemplate().send(errorChannel, getErrorMessageStrategy().buildErrorMessage(t, null)); sent = true; } catch (Throwable errorDeliveryError) { //NOSONAR // message will be logged only if (this.logger.isWarnEnabled()) { this.logger.warn("Error message was not delivered.", errorDeliveryError); } if (errorDeliveryError instanceof Error) { throw ((Error) errorDeliveryError); } } } if (!sent && this.logger.isErrorEnabled()) { Message<?> failedMessage = (t instanceof MessagingException) ? ((MessagingException) t).getFailedMessage() : null; if (failedMessage != null) { this.logger.error("failure occurred in messaging task with message: " + failedMessage, t); } else { this.logger.error("failure occurred in messaging task", t); } } }
@Override protected void onInit() { super.onInit(); if (!this.extractPayload) { Assert.notNull(this.serializer, "'serializer' has to be provided where 'extractPayload == false'."); } if (this.taskExecutor == null) { String beanName = this.getComponentName(); this.taskExecutor = new SimpleAsyncTaskExecutor((beanName == null ? "" : beanName + "-") + this.getComponentType()); } if (!(this.taskExecutor instanceof ErrorHandlingTaskExecutor) && this.getBeanFactory() != null) { MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler(new BeanFactoryChannelResolver(getBeanFactory())); errorHandler.setDefaultErrorChannel(getErrorChannel()); this.taskExecutor = new ErrorHandlingTaskExecutor(this.taskExecutor, errorHandler); } }
pollingChannelAdapter.setTaskScheduler(taskScheduler); MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler(); Log errorHandlerLogger = TestUtils.getPropertyValue(errorHandler, "logger", Log.class); errorHandlerLogger = spy(errorHandlerLogger);