To implement custom exception handler:
- Specify the endpoint adress, which handles all error types and Exceptions, in the
web.xml
:
<error-page>
<location>/error</location>
</error-page>
Add corresponding error handler method:
@RequestMapping(value = "/error", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> handleError(
@RequestAttribute(name = "javax.servlet.error.status_code",
required = false) Integer errorCode,
@RequestAttribute(name = "javax.servlet.error.exception",
required = false) Throwable exception) {
if (errorCode == null) {
errorCode = 500;
}
String reasonPhrase;
if (exception != null) {
Throwable cause = exception.getCause();
if (cause != null) {
reasonPhrase = cause.getMessage();
} else {
reasonPhrase = exception.getMessage();
}
} else {
reasonPhrase = HttpStatus.valueOf(errorCode).getReasonPhrase();
}
HashMap<String, String> serverResponse = new HashMap<>();
serverResponse.put("errorCode", String.valueOf(errorCode));
serverResponse.put("reasonPhrase", reasonPhrase);
return ResponseEntity.status(errorCode).body(serverResponse);
}
Sending an ajax
request from the frontend (I wrote it in AngularJS
):
http({
url: '/someEndpoint',
method: "POST",
headers: {'Content-Type': undefined },
}).then((response) => successCallback(response),
(response) => errorCallback(response));
let successCallback = function(response) {
// console.log(response);
mdToast.show({
position: 'bottom right',
template: scope.templates.success('Success message'),
});
};
let errorCallback = function(response) {
// console.log(response);
mdToast.show({
position: 'bottom right',
template: scope.templates.error('Error message'),
});
if (response && response.data && response.data.reasonPhrase) {
mdToast.show({
position: 'bottom right',
template: scope.templates.error(response.data.reasonPhrase),
});
}
};
First it says, that there was an error, and then says what error it was.
For example, if the server returns something unexpected:
@GetMapping({"/", "/index.html"})
public ResponseEntity<?> getMainPage() throws Exception {
throw new Exception("Something unexpected..");
}
The client receives this kind of JSON
message:
{
"reasonPhrase": "Something unexpected..",
"errorCode": "500"
}
Or server may return something less unexpected:
@GetMapping({"/", "/index.html"})
public ResponseEntity<?> getMainPage() {
try {
// expected actions
// . . .
} catch (Exception e) {
HashMap<String, String> serverResponse = new HashMap<>();
serverResponse.put("errorCode", "403"));
serverResponse.put("reasonPhrase", "Forbidden");
return ResponseEntity.status(403).body(serverResponse);
}
}
Client:
{
"reasonPhrase": "Forbidden",
"errorCode": "403"
}
Also, if a client requests an unreachable resource or a page that does not exist, then he receives:
{
"reasonPhrase": "Not Found",
"errorCode": "404"
}