Ismael Ezequiel
Ismael Ezequiel

Reputation: 184

How I create an error handler (404, 500...) in Spring Boot/MVC

For some hours I'm trying to create a custom global error handler in Spring Boot/MVC. I've read a lot of articles and nothing.

That is my error class:

I tried create a class like that

@Controller
public class ErrorPagesController {

    @RequestMapping("/404")
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String notFound() {
        return "/error/404";
    }

    @RequestMapping("/403")
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public String forbidden() {
        return "/error/403";
    }

    @RequestMapping("/500")
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String internalServerError() {
        return "/error/500";
    }

}

Upvotes: 13

Views: 52019

Answers (5)

Eduardo
Eduardo

Reputation: 2279

Update for spring boot

Custom error pages

If you want to display a custom HTML error page for a given status code, you add a file to an /error folder. Error pages can either be static HTML (i.e. added under any of the static resource folders) or built using templates. The name of the file should be the exact status code or a series mask.

For example, to map 404 to a static HTML file, your folder structure would look like this

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

Source

Upvotes: 6

Dr. Mehmet Ali ATICI
Dr. Mehmet Ali ATICI

Reputation: 609

You may try the following code:

@ControllerAdvice
public class ExceptionController {
    @ExceptionHandler(Exception.class)
    public ModelAndView handleError(HttpServletRequest request, Exception e)   {
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Request: " + request.getRequestURL() + " raised " + e);
        return new ModelAndView("error");
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public ModelAndView handleError404(HttpServletRequest request, Exception e)   {
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Request: " + request.getRequestURL() + " raised " + e);
        return new ModelAndView("404");
    }
}

Upvotes: 8

Alex Fernandez
Alex Fernandez

Reputation: 1942

Additional to @Arash You could add a new BaseController class that you can extends,that handles the conversion from exception to http response.

     import com.alexfrndz.pojo.ErrorResponse;
     import com.alexfrndz.pojo.Error;
     import com.alexfrndz.pojo.exceptions.NotFoundException;
     import org.springframework.http.HttpStatus;
     import org.springframework.http.ResponseEntity;
     import org.springframework.web.bind.annotation.ExceptionHandler;
     import org.springframework.web.bind.annotation.ResponseBody;
     import org.springframework.web.bind.annotation.ResponseStatus;

     import javax.persistence.NoResultException;
     import javax.servlet.http.HttpServletRequest;
     import java.util.List;

     @Slf4j
     public class BaseController {

    @ExceptionHandler(NoResultException.class)
    public ResponseEntity<Exception> handleNoResultException(
            NoResultException nre) {
        log.error("> handleNoResultException");
        log.error("- NoResultException: ", nre);
        log.error("< handleNoResultException");
        return new ResponseEntity<Exception>(HttpStatus.NOT_FOUND);
    }


    @ExceptionHandler(Exception.class)
    public ResponseEntity<Exception> handleException(Exception e) {
        log.error("> handleException");
        log.error("- Exception: ", e);
        log.error("< handleException");
        return new ResponseEntity<Exception>(e,
                HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(NotFoundException.class)
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ResponseBody
    public ErrorResponse handleNotFoundError(HttpServletRequest req, NotFoundException exception) {
        List<Error> errors = Lists.newArrayList();
        errors.add(new Error(String.valueOf(exception.getCode()), exception.getMessage()));
        return new ErrorResponse(errors);
    }
   }

Upvotes: 8

Arash
Arash

Reputation: 12465

@ControllerAdvice
 public class ErrorHandler {

public RestErrorHandler() {
}

@ExceptionHandler(YourException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public XXX processException(Exception ex){}

You need a class like this. Add a method for each exception, and annotate it as you please - @ResponseBody etc.

Upvotes: 4

AchillesVan
AchillesVan

Reputation: 4366

Hope this will help: Create a class say: NoProductsFoundException that extends runtimexception.

    import org.springframework.http.HttpStatus;
    import org.springframework.web.bind.annotation.ResponseStatus;

    @ResponseStatus(value=HttpStatus.NOT_FOUND, reason="No products found under this category")
    public class NoProductsFoundException extends RuntimeException{

    private static final long serialVersionUID =3935230281455340039L;
    }

Then in your productcontroller:

    @RequestMapping("/{category}")
    public String getProductsByCategory(Model
    model,@PathVariable("category") String category) {

   List<Product> products = productService.getProductsByCategory(category);

   if (products == null || products.isEmpty()) {
   throw new NoProductsFoundException ();
   }
   model.addAttribute("products", products);
   return "products";
}

enter image description here

Upvotes: 3

Related Questions