Skip to content

Conversation

@jroper
Copy link
Member

@jroper jroper commented Sep 25, 2014

  • Play will by default try and load one of these from the root package called ErrorHandler
  • If none is found, it will fallback to one that delegates to Global, so that Global.onError etc methods still work for legacy apps
  • Added a new mechanism to the Reflect utils to load bindings for either a Scala interface, or a Java interface with an adapter to the Scala interface
  • Updated documentation, including removing documentation on old Global methods

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why aren’t we sure here that there is an Application?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may have failed to compile or load (in dev mode). At some point I'd like to change things so that if it does fail to compile or load, an error application is returned that just responds to every request by rendering the error, that will make so much of the logic here so much simpler. But I think that's a separate change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was thinking of doing something like this when I was writing the Akka HTTP backend. Or at least a MaybeLoadedApplication which wraps either a loaded application or a not-loaded application and which the Netty and Akka HTTP servers can send requests too.

@julienrf
Copy link
Contributor

I don’t think this is a good idea to reflectively load the HttpErrorHandler. We should reduce reflection usage to the minimum: ApplicationLoader.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not have this file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not? Unfortunately, we need to instantiate RequestHeaders in the tests, and there's no other way to do it. Now that the app doesn't depend so much on global state, we can start moving tests out of the integration test project, but some things are needed to do that, such as a way to instantiate a RequestHeader.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t see the point of having two separate types, Request and FakeRequest. Why not just have Request? Just put the required methods in this type.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request is also just a trait that doesn't have any public concrete implementations.

While I completely agree with you, providing either Request or RequestHeader case classes are separate changes in their own right that will have a fundamental impact on Play's public API. They need to be carefully thought through, in particular, we'd like to preparse many headers, including the session, and make them strongly typed, but we don't want two sources of truth (both the headers map and the strongly typed parsed values).

In contrast, this FakeRequest is just something introduced for Play's tests, it is not public API, and so can be done with little thought. I hope some day we can get rid of it, but that day isn't today.

@jroper
Copy link
Member Author

jroper commented Sep 25, 2014

If you're using runtime dependency injection, you're using reflection anyway everywhere to instantiate everything. If you're using compile time dependency injection, then reflection is just to load the ApplicationLoader.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "malformated" -> "malformed" or "badly formatted"

@richdougherty
Copy link
Member

LGTM

James and I had a bit of a talk offline about this PR. I'll just mention some of the things I raised with James. I didn't have any solutions to these issues, these were just comments.

  • Passing around Mode.Mode is a pet peeve of mine. It would be nice to get rid of the separate methods for dev and prod mode and instead bind different error handlers for dev and prod mode. However I don't think we can easily do this at the moment, because by binding different dev and prod mode error handlers we would make the default error handling logic into something that can only be known at runtime. So if a user wants access to the default error handler, they can't access the logic by overriding DefaultErrorHandler. They would need to get the error handler bound at runtime. Unfortunately if they bind their own error handler then they would override any default error handler.
  • It's kind of annoying to have to thread the error handler all over the place. There are some places that it isn't passed yet (body parsers). Some random ideas to make it easier to do error handling: pass error handlers in the request context when handling requests, have handlers return a different kind of Result or throw an exception to express that they want to display an error using the default error handling logic. These are my own ideas, but I don't like them very much. :) There are other objects (e.g. ExecutionContexts) that we'll need to thread everywhere too, so maybe in the future we'll find a solution to make passing these objects a bit easier, e.g. we might group some common objects together into a single object, so we only have to thread a single object around the place. We just need to be careful we don't accidentally recreate a "God" object like Application or Global!

* Play will by default try and load one of these from the root package
  called ErrorHandler
* If none is found, it will fallback to one that delegates to Global, so
  that Global.onError etc methods still work for legacy apps
* Added a new mechanism to the Reflect utils to load bindings for either
  a Scala interface, or a Java interface with an adapter to the Scala
  interface
* Updated documentation, including removing documentation on old Global
  methods
@jroper
Copy link
Member Author

jroper commented Sep 29, 2014

@play-pull-request-validator again please

richdougherty added a commit that referenced this pull request Sep 29, 2014
Extracted HttpErrorHandler interface from Global
@richdougherty richdougherty merged commit 11161bf into playframework:master Sep 29, 2014
@jroper jroper deleted the http-error-handler branch March 5, 2015 00:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants