Skip to content

Instantly share code, notes, and snippets.

@itzg
Last active November 20, 2019 18:02
Show Gist options
  • Select an option

  • Save itzg/ae402158e9952be2d45f78a6196e8f7f to your computer and use it in GitHub Desktop.

Select an option

Save itzg/ae402158e9952be2d45f78a6196e8f7f to your computer and use it in GitHub Desktop.
Spring MVC controller advice for handling custom exceptions
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.ServletWebRequest;
@ControllerAdvice
@ResponseBody
public class RestExceptionHandler {
private final ErrorAttributes errorAttributes;
@Autowired
public RestExceptionHandler(ErrorAttributes errorAttributes) {
this.errorAttributes = errorAttributes;
}
@ExceptionHandler({NotFoundException.class})
public ResponseEntity<?> handleCustomExceptions(
HttpServletRequest request) {
return respondWith(request, HttpStatus.NOT_FOUND);
}
private ResponseEntity<?> respondWith(HttpServletRequest request,
HttpStatus status) {
Map<String, Object> body = getErrorAttributes(request);
body.put("status", status.value());
return new ResponseEntity<>(body, status);
}
private Map<String, Object> getErrorAttributes(HttpServletRequest request) {
final ServletWebRequest webRequest = new ServletWebRequest(request);
return errorAttributes.getErrorAttributes(webRequest, false);
}
}
@itzg
Copy link
Copy Markdown
Author

itzg commented Jun 5, 2019

For a validation error response is

{
  "timestamp": "2019-06-05T15:46:57.502+0000",
  "status": 400,
  "error": "Bad Request",
  "errors": [
    {
      "codes": [
        "PrivateZoneName.zoneCreatePrivate.name",
        "PrivateZoneName.name",
        "PrivateZoneName.java.lang.String",
        "PrivateZoneName"
      ],
      "arguments": [
        {
          "codes": [
            "zoneCreatePrivate.name",
            "name"
          ],
          "arguments": null,
          "defaultMessage": "name",
          "code": "name"
        }
      ],
      "defaultMessage": "zone name must be private",
      "objectName": "zoneCreatePrivate",
      "field": "name",
      "rejectedValue": null,
      "bindingFailure": false,
      "code": "PrivateZoneName"
    },
    {
      "codes": [
        "NotBlank.zoneCreatePrivate.name",
        "NotBlank.name",
        "NotBlank.java.lang.String",
        "NotBlank"
      ],
      "arguments": [
        {
          "codes": [
            "zoneCreatePrivate.name",
            "name"
          ],
          "arguments": null,
          "defaultMessage": "name",
          "code": "name"
        }
      ],
      "defaultMessage": "may not be empty",
      "objectName": "zoneCreatePrivate",
      "field": "name",
      "rejectedValue": null,
      "bindingFailure": false,
      "code": "NotBlank"
    }
  ],
  "message": "Validation failed for object='zoneCreatePrivate'. Error count: 2",
  "path": "/api/tenant/aaaaaa/zones"
}

@itzg
Copy link
Copy Markdown
Author

itzg commented Jun 5, 2019

When the custom exception is handled, example response is

{
  "timestamp": "2019-06-05T15:54:26.292+0000",
  "status": 404,
  "error": "None",
  "message": "No zone found named asdfasdf"
}

@itzg
Copy link
Copy Markdown
Author

itzg commented Jun 5, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment