2

I have a simple rest endpoint as follows:

@RequestMapping(method = RequestMethod.GET, value = "/error")
public ResponseEntity<String> genericErrorHandler() {
    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("");
}

The purpose of this is to make it as a default error response for my REST API. However, this endpoint is never recognized by Spring. It is never called. The problem is the path itself. It is "/error". If I change it to anything else, like "/foo", it will work.

According to this docs:

At start-up, Spring Boot tries to find a mapping for /error. By convention, a URL ending in /error maps to a logical view of the same name: error. If no mapping from /error to a View can be found, Spring Boot defines its own fall-back error page - the so-called “Whitelabel Error Page” (a minimal page with just the HTTP status information and any error details, such as the message from an uncaught exception).

So. whenever an exception is thrown and it is not handled by any @ExceptionHandler annotated method, then Spring boot will call this endpoint (/error). I am simply trying to get rid of the default "Whitelabel Error Page" that spring boot provides, and use this endpoint instead. Am I misunderstanding the purpose of the /error page? Or what is it that I am doing incorrectly?

================UPDATE==================

So, I was able to get the /error endpoint to work by forcing the class, which contains the /error endpoint, to implement interface ErrorController, as suggested in the possible duplicate post

However, after this, ALL my endpoints get rerouted to this /error. Meaning, all things that worked before, like /user/1, or /orders, now fall back to /error. Do you have any idea what went wrong here?

Here is where /error is defined:

@RestController
@RequestMapping("/error")
public class FallbackErrorController implements ErrorController {
    private static final String ERROR_PATH = "/error";

    @RequestMapping(method = RequestMethod.GET)
    public ResponseEntity<String> genericErrorHandler() {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("A fake error");
    }

    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }
}
Simo
  • 2,292
  • 5
  • 30
  • 45
  • 1
    Possible duplicate of [Spring Boot Remove Whitelabel Error Page](https://stackoverflow.com/questions/25356781/spring-boot-remove-whitelabel-error-page) – filpa Mar 31 '18 at 21:43
  • 2
    Straight from the Spring boot’s reference guide https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-error-handling – isank-a Mar 31 '18 at 21:57
  • This should ideally not be happening, do you have any Interceptors with preHandle()? – bitscanbyte Apr 01 '18 at 02:59
  • @bitscanbyte No. The app is really simple; say, it has just another rest controller and that's it. – Simo Apr 01 '18 at 06:00
  • Looks like more information may be required, as your ErrorController configuration seems ok, although you should ideally remove `(method = RequestMethod.GET)` see impl of `BasicErrorController`. Pls share a link to GH, etc with your complete setup. – bitscanbyte Apr 01 '18 at 07:02
  • Complete code is here. https://github.com/spring-guides/tut-bookmarks/tree/master/rest/src/main/java/bookmarks It is a sample project by Spring itself. Please pay attention to the sub-project "rest" only. Inside the "bookmarks" package, I simply added class FallbackErrorController (see the main post), and that's it. Please lemme know how it works for you. – Simo Apr 01 '18 at 07:32
  • @bitscanbyte did you get a chance to try the code? Please see my previous comment. – Simo Apr 01 '18 at 19:00
  • Can you share the request sample? or share a simpler example with just your rest endpoint, creating this using spring boot should be much simpler. This sample project from spring has multiple examples and I wouldn't have time to read through the usages on GH – bitscanbyte Apr 02 '18 at 05:10
  • @bitscanbyte Here it is: http://localhost:port/jlong/bookmarks, or http://localhost:port/jlong/bookmarks/1. The error endpoint is http://localhost:port/error. The port is normally printed out on the console when you run the app. – Simo Apr 02 '18 at 22:06
  • It's not what I meant, this example requires authentication, only hitting the above request will give a 401. You need to give the complete request (with headers) you are hitting for which you face this issue, e.g., a `curl` request, you can get this from whichever Rest client you are using. – bitscanbyte Apr 03 '18 at 06:45
  • @bitscanbyte you open it in a browser, enter "user" as login, and password (printed on the console when you run the spring boot app). It's that plain and simple. The default login is provided by spring automatically. No needs for using curl here. – Simo Apr 03 '18 at 21:26
  • To be more specific: On Chrome, open http://localhost:port/jlong/bookmarks. You will see a dialog asking for username and password. After logging in, you'll see the json representing all the bookmarks. Then change the URL to http://localhost:port/error, and you'll see the error message. That is how it is supposed to work. But now all endpoints are rerouted to /error for some reason. – Simo Apr 03 '18 at 21:53
  • This is not a correct way of debugging an issue, and due to this fact only you have been facing this issue. Your ErrorController is working fine, you must not be paying attention to the default password that the application uses is random and changes everytime you restart the application. If you are experiencing this from the browser then it will be sending the same password everytime. Use a simple GET request from a client like Postman and enter the credentials in `Basic Auth` and you should be able to test successfully. – bitscanbyte Apr 04 '18 at 02:48
  • I just noticed the same thing with my boot project. It first hit the correct endpoint, then somehow stopped at the breakpoint within /error handler, similar to your genericErrorHandler, tho the browser would end up with the correct view, but it did hit /error in the middle of some chain processing. Strange. – Nathan W Apr 05 '18 at 18:49
  • More interestingly, after I removed the customized /error code, and only using Spring's default error handler, set a couple of breakpoints in Spring's BasicErrorController, it'd stop there every time for every valid request (after user authentication) with errors, showing 404 by its getStatus.. It only occurs to endpoints that are required authenticated users. Looks like a Spring bug. – Nathan W Apr 05 '18 at 22:10
  • I meant it shouldn't go thru the error handler if there isn't an error, even tho it eventually shows the expected result/page. And, it seems only doing that for endpoints intended for authenticated users. – Nathan W Apr 05 '18 at 22:20
  • Were you able to resolve this issue? – Rachit Dhall Sep 17 '19 at 18:59

1 Answers1

2

This is what worked for me:

@Override
public String getErrorPath() {
return PATH;
}    

Returns the path of the error page. i.e.

private static final String PATH = "/error";

now it is redirected to the /error route.

Sequencially,

@Controller
@RequestMapping(value="/")
public class HomeController implements ErrorController{

private static final String PATH = "/error";

@GetMapping(value=PATH)
    public String error(Model model) {

        return "error/error404";
    }

@Override
    public String getErrorPath() {
        return PATH;
    }
}
suman heuju
  • 121
  • 3