Spring integration: exception is not thrown to error channel

36 views Asked by At

I have spring integration channels, the one of them is dbSavingChannel. And I would intercept the thrown exception in my exception handler 'handleErroredMsg', but the program reaches the line 'throw new RuntimeException("conflict");' and does not reach the exception handler. What do I need to do that to intercept exception correctly?

    @Async("myExecutor")
    @ServiceActivator(inputChannel = "dbSavingChannel")
    public void saveEntityToDb(final Message<ObjEntity> msg) {
        ObjEntity entity = msg.getPayload();
        List<ObjEntity> conflictList = repository.findAllById(entity.getId());
        if (!conflictList.isEmpty()) {
            throw new RuntimeException("conflict");
        }
        ...
    }
    

    @ServiceActivator(inputChannel = "errorChannel")
    public Message<?> errorHandling(final Message<MessageHandlingException> msg) {
        return errorHandler.handleErroredMsg(msg);
    }   
    @Bean("myExecutor")
    public TaskExecutor getAsyncEsppExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        int cores = Runtime.getRuntime().availableProcessors();
        executor.setCorePoolSize(cores);
        executor.setMaxPoolSize(cores);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setThreadNamePrefix("eThread-");
        return executor;
    }

ErrorHandler:

    public Message<?> handleErroredMsg(Message<MessageHandlingException> msg) {
        Throwable cause = msg.getPayload().getCause();
        ...
    }

The exception appears in the console but is not caught in the handler.

If I remove @Async("myExecutor") - It works, but how can I handle exception with using @Async ?

1

There are 1 answers

0
Artem Bilan On

The @Async("myExecutor") is not a part of Spring Integration. If you'd like to do that Spring Integration way (I mean async process), then you need to look into making that dbSavingChannel as an ExecutorChannel: https://docs.spring.io/spring-integration/reference/channel/implementations.html#executor-channel.

Then Spring Integration wraps that provided TaskExecutor to the ErrorHandlingTaskExecutor - and an ErrorMessage is going to be sent to the global errorChannel.

If you still would prefer to use @Async, then you need to use that ErrorHandlingTaskExecutor manually and supply it with the MessagePublishingErrorHandler.

See more info in docs: https://docs.spring.io/spring-integration/reference/error-handling.html