Having troubles with using Exception thrown in Axon @QueryHandler that is annotated as Spring @ResponseStatus. The original Exception is swallowed by QueryHandler and Axon specific AxonServerRemoteQueryHandlingException is thrown what actually gives 500 when spring responds to client
It is still possible to harvest some info from the Axon exception, like the original "Entity not found" message but not Exception type nor any other info the original exception holds.
Q1: is there is any way how to promote the exception thrown in the Query handler into Spring response as 404
Spring Exception handler
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class NotFoundException extends ServiceException() {
...
}
Axon query handler
@QueryHandler
public Application getApplicationById(ApplicationByIdQuery query) {
return applicationRepository.findById(query.getId())
.orElseThrow(() -> new NotFoundException(Application.class, query.getId()));
}
Spring controller
@Autowired
QueryGateway queryGateway;
@GetMapping(path = "/{applicationId}")
public CompletableFuture<Application> getApplication(@PathVariable String applicationId) {
return queryGateway.query(new ApplicationByIdQuery(applicationId), ResponseTypes.instanceOf(Application.class));
}
Actual result json:
{
"timestamp": "2019-02-08T08:04:03.629+0000",
"status": 500,
"error": "Internal Server Error",
"message": "An exception was thrown by the remote message handling component.",
"path": "/api/applications/dff59c46-baf1-40f5-8a21-9286d1f8e36fx"
}
Q2: My another question is why not to use regular JPA Query API directly but use the QueryHandler from Axon. The projection tables are regular JPA tables and could be questioned via very powerful Spring JPA. Is it because direct querying does not ensure projection data consistency? I went through many examples, most of them use the direct access (see bellow), the rest do not solve exceptions thrown from underlaying QueryHandler
@Autowired
ApplicationRepository applicationRepository;
public CompletableFuture<Application> getApplication(@PathVariable String applicationId) {
return CompletableFuture.supplyAsync(() -> applicationRepository.findById(applicationId)
.orElseThrow(() -> new NotFoundException(Application.class, applicationId)));
}