Siva Nadupuru
3 min readAug 31, 2020

Spring Boot Error and Exception Handling

In real time application development we use Exception handling concept, to smooth termination of the program. it will convert system error messages into user friendly error messages. but in Spring boot framework , they already implemented the Exception handling concept , here we need to understand how the exceptions and Errors will handled internally in Spring Boot framework.

Here the below diagram shows , Error flow in Spring Boot

In spring /Spring boot handled errors by using ErrorController(I), it will implements BasicErrorController(C), that provides two methods

errorHtml():ModelAndView (call trigger from browser)
error(): ResponseEntity<T> (call trigger from non-browser/client app/postman /Any rest clients etc..)

Work flow on Success
Client -> Request -> DispatcherServlet -> doDispatch(req,resp) -> HandlerMapping -> Controller-> DispatcherServlet -> ViewResolver -> View -> Model (read) -> DispatcherServlet-> UI

Work flow on failure:

Client -> Request -> DispatcherServlet -> doDispatch(req,resp) -> HandlerMapping -> Controller-> DispatcherServlet -> BasicErrorController -> Response

DefaultErrorAttributes:-
BasicErrorController collects all error details as Map<String,Object>
which holds details like ‘status,error, path, timestamp..etc…This ErrorMap only called as Error Attributes, this is given as final response to client.

In spring boot, if you want customize the error page white label error, we can do that.

Custom Error pages: We can create error.html file under ‘templates’ folder and design based on requirement. This gets executed on any problem (Http Status : 4xx and 5xx). ie 400,401,403,404…500,501..etc… only one page is executed ie: error.html

specific error page create under error folder with Errorcode.html(ex: 404.html,500.html..). if given code is not matched, it will goes to error.html.

Custom ErrorController: We can customize default ErrorController code. Spring Boot has provided BasicErrorController(C). If we define impl for ErrorController(I) then Spring boot chooses our class as priority and also
error.html , 404.html, 5xx.html will not work.

Using Error Attributes in Custom Controller:

Spring boot by default provides few attribute for error like
timestamp, status, path , message, exception, trace..etc

→ To use them in our custom error controller, just autowire that property.

@Autowired
private ErrorAttributes errorAttributes;

=> To read all properties with value for current request.
ServletWebRequest webRequest = new ServletWebRequest(req);

Map<String, Object> errors = errorAttributes.getErrorAttributes(webRequest, true);

package com.error.controller;

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.boot.web.servlet.error.ErrorController;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.context.request.ServletWebRequest;

@Controller

public class MyCustomErrorControllerWithAttrs implements ErrorController {

@Autowired

private ErrorAttributes errorAttributes;

@RequestMapping(“/error”)

public @ResponseBody String handleProblem(HttpServletRequest req)

{

ServletWebRequest webRequest=new ServletWebRequest(req);

Map<String,Object> errors=errorAttributes.getErrorAttributes(webRequest, true);

StringBuilder builder = new StringBuilder();

builder.append(“<html><body>”);

builder.append(“<h2>ERROR DETAILS</h2>”);

builder.append(“<table border=’1'>”);

errors.forEach((k,v)->{

builder.append(“<table>”);

builder.append(“<tr>”);

builder.append(“<td>”).append(k).append(“</td>”);

builder.append(“<td>”).append(v).append(“</td>”);

builder.append(“</tr>”);

});

builder.append(“</table>”);

builder.append(“</body></html>”);

return builder.toString();

}

@Override

public String getErrorPath() {

return “/error”;

}

}

Return Error Response as JSON Type: Make sure that your controller method retuns non-string type (Lis/Set/Map) Apply @ResponseBody over method.

package com.error.controller;

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.boot.web.servlet.error.ErrorController;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.context.request.ServletWebRequest;

@Controller

public class MyCustomErrorControllerWithAttrsJson implements ErrorController {

@Autowired

private ErrorAttributes errorAttributes;

@RequestMapping(“/error”)

public @ResponseBody Map<String, Object> handleProblem(HttpServletRequest req)

{

ServletWebRequest webRequest = new ServletWebRequest(req);

@SuppressWarnings(“deprecation”)

Map<String, Object> errors = errorAttributes.getErrorAttributes(webRequest, true);

return errors;

}

@Override

public String getErrorPath() {

return “/error”;

}

}

. Customize ErrorAttributes (extends DefaultErrorAttributes)

# Simple Process:
in our custom ErrorController add our key-val pairs to Map<String,Object>
using method put(k,v).

@RequestMapping(“/error”)

public @ResponseBody Map<String, Object> handleProblem(HttpServletRequest req)

{

ServletWebRequest webRequest = new ServletWebRequest(req);

@SuppressWarnings(“deprecation”)

Map<String, Object> errors = errorAttributes.getErrorAttributes(webRequest, true);

errors.put(“Siva”, “java”);

return errors;

}

# Complex Process:
1) Our custom error controller should extend AbstractErrorController
2) Provide Param const for ErrorAttributes
3) Define one new class that extends DefaultErrorAttributes

Exception Handling in Spring Boot ReST

1. Default Error Message (Boot ReST) + @ResponseStatus
2. Customized Error Message — @ControllerAdvice, @ExceptionHandler

1. Default Error Message (Boot ReST) + @ResponseStatus
In this case we are using default message given by BasicErrorController#error
(ResponseEntity<T> type → JSON) format.

> Here, we can customize only Status and message

{
“timestamp”: “2020–09–03T07:56:41.693+00:00”,
“status”: 404,
“error”: “Not Found”,
“trace”: ….
“message”: “EMPLOYEE NOT EXIST 50”,
“path”: “/find/50”
}

2. Customized Error Message — @ControllerAdvice, @ExceptionHandler:

Here we can complete completely json response,

{

“message”: “EMPLOYEE NOT EXIST 6”,

“code”: “NO_EMP_FOUND”,

“error”: “DATA NOT FOUND FOR GIVEN ID”,

“classType”: “Employee”

}

sample code for above explanation , please find from my git repo below

https://github.com/SivaNadupuri/SpringBootRestExceptionApp

https://github.com/SivaNadupuri/SpringBootMVCReSTErrorHandling

Siva Nadupuru
Siva Nadupuru

Written by Siva Nadupuru

Working as Java Full Stack Developer

No responses yet