silverstripe / silverstripe-framework

Silverstripe Framework, the MVC framework that powers Silverstripe CMS
https://www.silverstripe.org
BSD 3-Clause "New" or "Revised" License
723 stars 821 forks source link

404 from root url not going through RequestHandler::httpError #9225

Open manja opened 5 years ago

manja commented 5 years ago

Affected Version

4.4.3

Description

When opening any route which is not defined inside SilverStripe\Control\Director:rules part of yml config file, HTTP 404 is thrown directly from Director, line 316, completely avoiding RequestHandler::httpError and all of its hooks.

Steps to Reproduce

Simply open any non-existing root url of framework only project, like /this-route-does-not-exist and you'll get No URL rule was matched error.

dnsl48 commented 5 years ago

This sounds like a correct behaviour, since no appropriate RequestHandlers could be found by the routing rules. I guess, you could create a generic all-inclusive rule and assign a RequestHandler implementation you'd like?

manja commented 5 years ago

Yes, I created all-inclusive rule at the end of routes as a quick fix, so I ended up with 5 lines of code for a controller whose only function is to throw error. But that's not the solution IMHO.

While you may be correct that no appropriate RequestHandler was found - framework still throws 404 error. Which should be caught by RequestHandler::httpError and allowed to hook into. But no - it throws error directly, without any option to customize output. What if request was ajax and JSON was expected? Framework doesn't care - here's one line of plain text.

With this behaviour - we have two different use cases if 404 appears:

  1. Sub-url of a controller: RequestHandler::httpError fires up and allows hooking to onBefore/onAfter methods. One can make nice and neat error pages, like 404 and 500.
  2. Root-url: Boom. Error. No hooks. One line of a text. No option to customize.

CMS handles this differently, and unified. If you try to access url which has neither page nor controller, CMS shows customizable 404 page just like in case sub-url failed to resolve. One thing (http 404) via two different ways to trigger, one same output. Customizable.