I tried the 2 available kinds of Interceptors, both don’t really solve the problem as I described:
org.axonframework.messaging.MessageDispatchInterceptor
- This intercepts EVERY command, so you need logic to select the correct commands where the exception should be thrown
- It is not possible to throw checked exceptions, because the interface wants you to return a
java.util.function.BiFunction
. But the RuntimeException is not wrapped when using the CommandGateway
so you can catch it normally and create the 404 response
- there is no way to check if the aggregate Id exists in the
CommandMessage
in the Interceptor implementation, so an extra query is required that would run on every single command
org.axonframework.messaging.MessageHandlerInterceptor
You can catch the org.axonframework.modelling.command.AggregateNotFoundException
here (GREAT!).
But could not find a way to communicate that back at the time you use the CommandGateway
, you get the same CommandExecutionException
with Cause AxonServerRemoteCommandHandlingException
But it seems like at least in the AxonServerRemoteCommandHandlingException
the exception message of exceptions thrown in the Interceptor is uses, so at least the matching is easier. I don’t know if that is also true for other CommadBus implementations.
So seems like the only way to catch your own exceptions in the commandGateway is the MessageDispatchInterceptor
with RuntimeExceptions. But in any case, there is a query necessary to check if the aggregate Id exists, which is very bad in a interceptor in my opinion.
So the Interceptors don’t work for me, I am back at the 2 ways I described in the first message
For those that, like me, just did a tutorial using all defaults, I want to also share the code I used to register the handlers. The documented way wants you to provide your own org.axonframework.commandhandling.CommandBus
bean, which is very inconvenient because the auto-configured org.axonframework.axonserver.connector.command.AxonServerCommandBus
needs 8 dependencies to build and the axon starter doesn’t provide a “configurer” to register interceptors.
So I recommend to annotate the MessageXInterceptors with org.springframework.stereotype.Component
and then register them using a org.springframework.context.ApplicationListener
@Component
public static class InjectInterceptor implements ApplicationListener<ApplicationReadyEvent> {
private final CommandBus commandBus;
private final List<MessageDispatchInterceptor> dispatchInterceptors;
private final List<MessageHandlerInterceptor> handlerInterceptors;
public InjectInterceptor(
CommandBus commandBus,
List<MessageDispatchInterceptor> dispatchInterceptors,
List<MessageHandlerInterceptor> handlerInterceptors
) {
this.commandBus = commandBus;
this.dispatchInterceptors = dispatchInterceptors;
this.handlerInterceptors = handlerInterceptors;
}
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
dispatchInterceptors.forEach(commandBus::registerDispatchInterceptor);
handlerInterceptors.forEach(commandBus::registerHandlerInterceptor);
}
}