I have a fairly simple axon application that Im trying to apply some generic "catch all" exception handling logic to.
If I have a command that goes into an aggregate that throws some kind of exception e.g.
class UserAggregate {
//...
@CommandHandler()
public void on(CreateUserCommand cmd) {
Validate.notNull(cmd.getEmail(), "Email cannot be null");
//other processing
}
}
Then when I invoke this command from the Rest Controller, then the exception is far away from what I would expect
org.axonframework.commandhandling.CommandExecutionException: Email cannot be null at org.axonframework.axonserver.connector.ErrorCode.lambda$static$10(ErrorCode.java:88) at org.axonframework.axonserver.connector.ErrorCode.convert(ErrorCode.java:182) at org.axonframework.axonserver.connector.command.CommandSerializer.deserialize(CommandSerializer.java:157) at org.axonframework.axonserver.connector.command.AxonServerCommandBus$1.onNext(AxonServerCommandBus.java:313) at org.axonframework.axonserver.connector.command.AxonServerCommandBus$1.onNext(AxonServerCommandBus.java:306) at io.grpc.stub.ClientCalls$StreamObserverToCallListenerAdapter.onMessage(ClientCalls.java:429) at io.grpc.ForwardingClientCallListener.onMessage(ForwardingClientCallListener.java:33) at io.grpc.ForwardingClientCallListener.onMessage(ForwardingClientCallListener.java:33) at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInternal(ClientCallImpl.java:596) at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInContext(ClientCallImpl.java:581)
Granted the message is useful, however, this is not always a given. This can be mitigated when implementing an ExceptionHandler like so
@ExceptionHandler
public void handle(Exception exception) {
log.info("Caught Exception - {}", exception.getMessage(), exception);
}
This now gives me a stack trace pinpointing where the issue actually came from, however, this comes at the cost of having to write such an ExceptionHandler everywhere I would like to invoke this command.
Is there a more generic way to log these exceptions without having to impose the ExceptionHandler on every class issueing commands?