@Autowired
void commandBus(ReactorCommandGateway reactiveGateway) {
reactiveGateway.registerResultHandlerInterceptor(
(msg, results) -> results
.onErrorMap(error -> new CommandExecutionException(
"An exception has occurred during command execution", error,
exceptionDetails(error, msg.getIdentifier())
))
);
}
private BusinessErrorDetails exceptionDetails(Throwable throwable, String entityName) {
if (throwable instanceof CustomBusinessException customBusinessException) {
return new BusinessErrorDetails(
customBusinessException.getClass().getName(), customBusinessException.getHttpStatus(),
customBusinessException.getErrorCode(), customBusinessException.getErrorMessage()
);
} else if (throwable instanceof AggregateNotFoundException) {
return new BusinessErrorDetails(
throwable.getClass().getName(), HttpStatus.NOT_FOUND, null,
ENTITY_NOT_FOUND_MESSAGE.formatted(entityName)
);
} else {
return new BusinessErrorDetails(
throwable.getClass().getName(), HttpStatus.INTERNAL_SERVER_ERROR, null,
SERVER_ERROR_MESSAGE
);
}
}
With the above configuration, each time it goes to the else branch as it’s not able to detect the custom exception thrown from an aggregate. The throwable is an “org.axonframework.commandhandling.CommandExecutionException: The remote handler threw an exception” with no underlying cause, etc., except string details.
However, with the non-reactive implementation below, it works as expected and I’m able to differentiate between different exceptions and thus create exception details, before throwing CommandExecutionException.
@Override
public Object handle(UnitOfWork<? extends CommandMessage<?>> unitOfWork, InterceptorChain interceptorChain) {
try {
return interceptorChain.proceed();
} catch (Throwable e) {
throw new CommandExecutionException("An exception has occurred during command execution", e, exceptionDetails(e, "entityName"));
}
}
private BusinessErrorDetails exceptionDetails(Throwable throwable, String entityName) {
if (throwable instanceof CustomBusinessException customBusinessException) {
return new BusinessErrorDetails(
customBusinessException.getClass().getName(), customBusinessException.getHttpStatus(),
customBusinessException.getErrorCode(), customBusinessException.getErrorMessage()
);
} else if (throwable instanceof AggregateNotFoundException) {
return new BusinessErrorDetails(
throwable.getClass().getName(), HttpStatus.NOT_FOUND, null,
ENTITY_NOT_FOUND_MESSAGE.formatted(entityName)
);
} else {
return new BusinessErrorDetails(
throwable.getClass().getName(), HttpStatus.INTERNAL_SERVER_ERROR, null, SERVER_ERROR_MESSAGE
);
}
}