java - Spring Boot - Global Custom Exception Handling Mechanism using RestControllerAdvice -
am using spring boot restful web services.
trying setup global custom exception handling mechanism relies on @restcontrolleradvice can handle exceptions known not known.
pom.xml
<parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version>1.5.4.release</version> </parent> <properties> <java.version>1.8</java.version> </properties> <repositories> <repository> <id>spring-releases</id> <url>https://repo.spring.io/libs-release</url> </repository> </repositories> <pluginrepositories> <pluginrepository> <id>spring-releases</id> <url>https://repo.spring.io/libs-release</url> </pluginrepository> </pluginrepositories> <dependencies> <!-- spring --> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </dependency> </dependencies>
globalcontrollerexceptionhandler:
@restcontrolleradvice public class globalcontrollerexceptionhandler { private static final logger log = logger.getlogger(globalcontrollerexceptionhandler.class); @exceptionhandler(value = { constraintviolationexception.class }) @responsestatus(httpstatus.bad_request) public apierrorresponse constraintviolationexception(constraintviolationexception ex) { log.error(ex.getcause().tostring()); return new apierrorresponse(400, "bad request"); } @exceptionhandler(value = { nohandlerfoundexception.class }) @responsestatus(httpstatus.not_found) public apierrorresponse nohandlerfoundexception(exception ex) { log.error(ex.getcause().tostring()); return new apierrorresponse(404, "resource not found"); } @exceptionhandler(value = { exception.class }) @responsestatus(httpstatus.internal_server_error) public apierrorresponse unknownexception(exception ex) { log.error(ex.getcause().tostring()); return new apierrorresponse(500, "internal server error"); } }
apierrorresponse:
public class apierrorresponse { private int status; private string message; public apierrorresponse(int status, string message) { this.status = status; this.message = message; } public int getstatus() { return status; } public string getmessage() { return message; } @override public string tostring() { return new tostringbuilder(this).append(status) .append(message) .tostring(); } }
the problem when use 3rd party library something, unknown exception might 404 returned 500!
e.g. using elasticsearch unknown index (deliberately see type of exception):
{ "timestamp": 1501236796640, "status": 500, "error": "internal server error", "exception": "org.elasticsearch.client.responseexception", "message": "post http://localhost:9200/fn3r4343/_search?pretty=true: http/1.1 404 not found" { "error": { "root_cause": [ { "type": "index_not_found_exception", "reason": "no such index", "resource.type": "index_or_alias", "resource.id": "fn3r4343", "index_uuid": "_na_", "index": "fn3r4343" } ], "type": "index_not_found_exception", "reason": "nosuchindex", "resource.type": "index_or_alias", "resource.id": "fn3r4343", "index_uuid": "_na_", "index": "fn3r4343" } { "root_cause" : [ { "type" :"index_not_found_exception", "reason" : no such index", "resource.type" : "index_or_alias", "resource.id" : "fn3r4343", "index_uuid" : "_na_", "index" : "fn3r4343" } ], [ { "type" : "index_not_found_exception", "reason" : "no such index", "resource.type" : "index_or_alias", "resource.id" : "fn3r4343", "index_uuid" : "_na_", "index" : "fn3r4343" }, "status": 404 ] } "path": "/myapp/search" }
as 1 can see, returns http 500 status in payload http 404!
what seeking return this:
{ "message" : "index not found exception", "status" : "http 404" }
and known http 404 exceptions:
{ "message" : "not found", "status" : "http 404" }
is there practice / mechanism use restcontrolleradvice catch type of exception , customize response json format readable / useful client using rest api?
this post isn't specific elastic search seeking how trying use @restcontrolleradvice handle type of exception put proper response client app...
the underlying exception being raised org.elasticsearch.client.responseexception
(you're using low-level rest client).
so in advice need add handler exception , return underlying status code:
@exceptionhandler(value = { responseexception.class }) public apierrorresponse nohandlerfoundexception(exception ex) { log.error(ex.getcause().tostring()); int status = ((responseexception) ex).getresponse().getstatusline().getstatuscode(); return new apierrorresponse(status, "<some message depending on status code>"); }
Comments
Post a Comment