playframework / playframework/play1
Wrong HTTP status (500) when content negotiation fails
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.6k
- Forks
- 671
- Avg merge
- 12d 15h
- Merged PRs (30d)
- 1
Description
Play1 has some content negotiation built in. For incoming requests it will try to establish the required return content type based on request header (Accept) and possibly also the extension of the last path segment.
In order to render the content in the requested content type, Play1 will look for a template with a certain extension. If it cannot find that template, it generates a 500 response and puts the following in the logs:
play.mvc.Controller.renderTemplate(Controller.java:813)
play.mvc.Controller.renderTemplate(Controller.java:782)
play.mvc.Controller.render(Controller.java:843)
controllers.SomeController.show(SomeController.java:42)
@7l7kg8b6p Internal Server Error (500) for request GET /some_controller/1234
Template not found (In {unknown source file. appclass=controllers.SomeController (compiled:true)} around line 42)
The template SomeController/show.txt does not exist.
The client will see this:
curl -H "Accept: text/plain" https://example.com/some_controller/1234
Template not found
The template SomeController/show.txt does not exist.
This behavior from Play1 makes my app very 500 happy. And I want 500s to be reserved for situation where either (a) we made a mistake programming the application, or (b) a service our app depends on is not available.
I'd argue that these 500s should be reclassified as (this is what I expect as behavior):
- 404 Not Found: in line with the
Template not founderror (I'd generalize this to resource or object not found). - 400 Bad Request: my preference as the application cannot deal with this type of request, it is defacto a request that does not fit with the API specs and hence is a mistake of the client.
500s in this case are a bit too heavy handed.
Maybe there is a way to mitigate this that I'm not aware of. As it looks I'd need to put guards in many of my controllers to prevent these "bad requests" to become 500s. Which leads me to the conclusion that 500s are the wrong default in this case.
I'd gladly submit a PR fixing this, but I'd like to know first if that'd be something the core contributors are interested in. And on top of that we need to figure out what the new status will be (400, 404, or something else) and if this then still requires any logging.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the failure through play.mvc.Controller.renderTemplate and Controller.render, using the example controllers.SomeController.show call and missing SomeController/show.txt template as the scenario. First determine whether content-negotiation failures should return 400 or 404 and how they should be logged; done means the chosen behavior is defined and implemented consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100