play1 icon indicating copy to clipboard operation
play1 copied to clipboard

[#2171] Action context access from error templates for routes-defined 404 actions

Open sant0s opened this issue 7 years ago • 1 comments

Lighthouse ticket

https://play.lighthouseapp.com/projects/57987-play-framework/tickets/2171

Framework version

1.5.3

Platform

Ubuntu 18.04, Oracle JDK 1.8.0_201

Description

For 404 actions declared in the routes file, action context items (e.g. controllers.Secure.Security.isConnected()) are not available to error templates and exceptions are thrown when they try to access them, resulting in HTTP 500 responses instead of HTTP 404 ones.

Without access to the session, HTTP 404 pages become more limited than other pages. This may cause the web app not be consistent across all pages.

Example: all the pages in a web app feature a navbar that displays "log in" if the user is logged out or "log out" if the user is logged in based on controllers.Secure.Security.isConnected(). The navbar may also display links to different web app actions depending on whether the user is logged in or not. All works well while a logged in user navigates across different pages, but as soon as a routes-defined 404 page is accessed, the navbar cannot be displayed like the other pages, cause there's no access to session information.

Actual behaviour reproduction steps

  1. Create a brand new Play! 1.5.3 app

  2. Add the secure module dependency (play -> secure) in conf/dependencies.yml and execute play dependencies

  3. Include the following code in app/views/errors/404.html and app/views/main.html:

<p>isConnected: ${controllers.Secure.Security.isConnected()}</p>
<p>Connected: ${controllers.Secure.Security.connected()}</p>
  1. In the routes file, add a route for a URL (1) and the 404 action. Example:

* /notfound 404

  1. Start the app

  2. Open a browser at the root URL (http://localhost:9000)

  3. The returned page successfully displays isConnected/Connected

  4. Point the browser at http://localhost:9000/notfound

  5. An HTTP 500 is returned and logs show a NPE:

Error during the 500 response generation

Execution exception (In {module:secure}/app/controllers/Secure.java around line 167)
NullPointerException occurred : null

play.exceptions.JavaExecutionException
	at play.templates.BaseTemplate.throwException(BaseTemplate.java:87)
	at play.templates.GroovyTemplate.internalRender(GroovyTemplate.java:307)
	at play.templates.Template.render(Template.java:28)
	at play.templates.GroovyTemplate.render(GroovyTemplate.java:230)
	at play.server.PlayHandler.serve500(PlayHandler.java:809)
	at Invocation.HTTP Request(Play!)
Caused by: java.lang.NullPointerException
	at controllers.Secure$Security.isConnected(Secure.java:167)
	at /app/views/errors/500.html.(line:9)
	at play.templates.GroovyTemplate.internalRender(GroovyTemplate.java:282)
	... 4 more

Expected behaviour

Session information should be available everywhere so web apps can be consistent across all pages.

Technical details

In class PlayHandler, the action context is reset in the init method, making it unavailable in templates.

sant0s avatar Apr 30 '18 08:04 sant0s

@xael-fry For some reason, ticket 2170/PR 1230 went through in Play! 1.5.2, but related ticket 2171/PR 1231 (this one) didn't. I've just rebased this pull request's branch onto the latest master and re-tested successfully i.e. checked that the issues reported in the ticket show up/do not show up before/after this fix is applied. Could this pull request be included in the next Play! release?

sant0s avatar Apr 11 '19 11:04 sant0s