Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppress "Circular view path [error]" error message #2001

Open
stepancheg opened this issue Nov 25, 2014 · 18 comments
Open

Suppress "Circular view path [error]" error message #2001

stepancheg opened this issue Nov 25, 2014 · 18 comments
Labels
type: enhancement A general enhancement
Milestone

Comments

@stepancheg
Copy link

  1. clone simple project: https://github.com/stepancheg/spring-boot-whitelabel

project contains controller with function

@RequestMapping("/throw")
@ResponseBody
public String t() {
    throw new RuntimeException();
}

and project calls

System.setProperty("error.whitelabel.enabled", "false");

before main.

  1. run main class (demo.Application)
  2. point browser to http://localhost:8080/throw

Browser displays white page. Expecting something more sensible. Tomcat default error handler would be perfect.

Using spring-boot 1.2.0.RC2.

@wilkinsona wilkinsona self-assigned this Nov 26, 2014
@wilkinsona
Copy link
Member

You also get a nasty error in the logs due to a circular view path:

2014-11-26 10:28:39.504 ERROR 2206 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost]           : Exception Processing ErrorPage[errorCode=0, location=/error]

javax.servlet.ServletException: Circular view path [error]: would dispatch back to the current handler URL [/error] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
    at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:205)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:145)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1228)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:721)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:468)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:391)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:318)
    at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:433)
    at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:299)
    at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:393)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

@wilkinsona
Copy link
Member

If your goal is to disable Boot's custom error page entirely then you need to turn off ErrorMvcAutoConfiguration. For example:

@Configuration 
@EnableAutoConfiguration(exclude=ErrorMvcAutoConfiguration.class)
public class Application {

}

I'm going to leave this issue open as we may want to:

  1. Provide a property to disable ErrorMvcAutoConfiguration
  2. Try to improve the behaviour when error.whitelabel.enabled is set to false and no alternative view has been provided

@Lucas-C
Copy link

Lucas-C commented Aug 4, 2015

I'm facing this issue too.
I wanted to have error.whitelabel.enabled=true on my development machine, but set to false in production.
However it seems that with @EnableAutoConfiguration(exclude=ErrorMvcAutoConfiguration.class) I cannot have the whitelabel page in "dev" anymore.
Also, are there other side effects when disabling ErrorMvcAutoConfiguration ?
I'd love if you could implement point 1. or 2..

@philwebb
Copy link
Member

philwebb commented Aug 4, 2015

@Lucas-C #2435 might give you a workaround.

@Lucas-C
Copy link

Lucas-C commented Aug 6, 2015

Looks great, thanks, but I won't be able to test it until next release

@snicoll
Copy link
Member

snicoll commented Aug 6, 2015

You can always test a snapshot easily via https://start.spring.io. M3 is going to be released soon.

@wilkinsona wilkinsona removed their assignment Mar 7, 2016
@snicoll
Copy link
Member

snicoll commented Apr 24, 2016

I can't reproduce the issue as it was described with 1.3.3 (careful: the property is now named server.error.whitelabel.enabled).

@wilkinsona can we do something about the warning in the logs?

@wilkinsona
Copy link
Member

I'm not sure, but that's why I left this issue open

@snicoll snicoll added priority: low type: enhancement A general enhancement labels Jan 11, 2017
@philwebb philwebb added this to the Backlog milestone Mar 22, 2018
@bclozel bclozel changed the title white page instead of exception when error.whitelabel.enabled=false Suppress "Circular view path [error]" error message Mar 22, 2018
@bclozel bclozel modified the milestones: Backlog, Icebox Aug 22, 2018
@dagnelies
Copy link

+1

@slyoldfox
Copy link

@wilkinsona
Sorry to dig up an old issue. But we have been seeing the same thing in our setup. I suppose it is a bit of a niche issue, since not many people actually turn off the default whitelabel behaviour, or just implement their own error view right away.

Much like the original issue report we have server.error.whitelabel.enabled=false and a @Controller throwing a RuntimeException.
This is with spring-boot 1.5.19 and embedded tomcat container.

On the frontend, you will indeed get a normal Tomcat error page. In the backend a nasty error will be logged.
javax.servlet.ServletException: Circular view path [error]: would dispatch back to the current handler URL [/error] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)

This is a majorly confusing error, although the documentation (https://docs.spring.io/spring-boot/docs/1.5.19.RELEASE/reference/html/howto-actuator.html) seems correct in mentioning that:

Set server.error.whitelabel.enabled=false to switch the default error page off which will restore the default of the servlet container that you are using. Note that Spring Boot will still attempt to resolve the error view so you’d probably add you own error page rather than disabling it completely.

It is ErrorPageCustomizer in ErrorMvcAutoConfiguration that actually registers an ErrorPage even though server.error.whitelabel.enabled is set to false.

In my opinion, registering the ErrorPage at that point should not be done by default, but maybe made optional. It feels as if two autoconfiguration things have been mixed, which leads to a confusing error being logged in the end.

  • Maybe with a property (server.error.register-default-error-page), by default true to keep backwards compatibility? Which allows turning off the registration of ErrorPage.
  • Maybe with a smart bean check on beanName "error", which would't exist because WhitelabelErrorViewConfiguration wouldn't have been handled, but could exist if you have defined your own error view.
  • Make ErrorPageCustomizer @ConditionalOnMissingBean ? So you can define your own empty implementation?

At the moment I use a hacky BeanPostProcessor to achieve the "wanted" behaviour (code for spring boot 2).

@Component
public class RemoveErrorPages implements BeanPostProcessor, EnvironmentAware {
    private Environment environment;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if( bean instanceof AbstractConfigurableWebServerFactory) {
            if( "false".equals( environment.getProperty("server.error.whitelabel.enabled") ) ) {
                ((AbstractConfigurableWebServerFactory) bean).getErrorPages().clear();
            }
        }
        return bean;
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
}

Of course using

spring:
  autoconfigure:
    exclude: 'org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration'

achieves the same.

The behaviour is also still present in Spring Boot 2.1.3.RELEASE so a fix for the confusing error message might still be needed. All configuration changes seem like a bit of a hack for fixing a confusing error message.

If you'd like a test project, I have one available to upload right away.

Thoughts?

@philwebb philwebb added the for: team-attention An issue we'd like other members of the team to review label Apr 8, 2019
@philwebb philwebb modified the milestones: General Backlog, 2.x Apr 24, 2019
@philwebb philwebb removed the for: team-attention An issue we'd like other members of the team to review label Apr 24, 2019
@wilkinsona
Copy link
Member

@slyoldfox Thank you for the analysis. We're still not really sure exactly what to do about this one. If you have a test project to share that could help us to figure things out, that would be much appreciated.

@slyoldfox
Copy link

@wilkinsona Of course, here you go

demo.zip

$ ./mvnw spring-boot:run

Open up http://localhost:8080/hello

Frontend will respond with an Internal Server Error with no whitelabel page as we disabled it with server.error.whitelabel.enabled.
In the console we will see a RuntimeException (expected), and after this two ServletException's (confusing).

It makes sense if you take into account the remarks above (that spring will still try to lookup /error - even though the user might not have configured one), but in the end the ServletExceptions are just confusing and I'm sure something smarter can be done to work around them.

Hope this helps!

@ianandkrpandey

This comment has been minimized.

@valkuc
Copy link

valkuc commented Feb 21, 2022

So, any out-of-box solution for this? Still reproducing on SB 2.6.3

@wilkinsona
Copy link
Member

wilkinsona commented Feb 21, 2022

@valkuc The solutions, such as they currently are, are described above. You already identified them in your description of #29919.

@atkawa7
Copy link

atkawa7 commented Sep 28, 2022

@philwebb @wilkinsona This is most likely to be related to HttpServletResponse.sendError issues. Are we going to replace all sendError with check for exception handlers and raise errors when enabled.

@jilvin
Copy link

jilvin commented May 8, 2023

I am able to circumvent this issue in an ad-hoc manner by setting server.error.path as something other than error which is the default. For example server.error.path = "error2" works enough even though the solution is not clean and proper.

Edit: It seems this was identified and shared already in #29919 .

@tbenbrahim
Copy link

tbenbrahim commented Feb 8, 2024

2024, and still facing the problem with a controller throwing an exception in an application where whitelabel error pages are disabled. Adding @EnableAutoConfiguration(exclude= ErrorMvcAutoConfiguration.class) resolves the issue, but this really should be handled in Spring to achieve the principle of least surprise. I expect to see a stack of the exception that caused a 500 response in my API, not a bunch of stack traces for Circular view path error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests