page.js
page.js copied to clipboard
No way to handle 404 with indeterminate execution order
I'm using page.js in an environment where I load individual components that set up their routes in an indeterminate order, for performance reasons.
This doesn't cause any problems with router handler precedence because I simply make the URIs not conflict.
However that is not a solution for 404 handling. I need a solution that would allow me to handle 404s without depending on it being the last route added.
Ideally there would be some support for precedence that does not rely on execution order.
Another simpler way, would be to give route handler the ability to determine if there are any subsequent matches to the route.
For instance, if next() returned true when a handler was called, or false on unhandled, I could do this at any place in my code without caring about order:
page('*', function(ctx, next) {
if(!next()) {
// handle 404
}
});
I see this as a side effect of carrying over the server-side express routing style into the browser, where you can not rely on the same assumptions about dependency execution order.
+1 - This is exactly what I need as well. My case is slightly different in that protected routes are not added until we verify the users authentication, which is async and long after we've registered the 404 handler.
@em you can use hack with setTimeout as workaround:
setTimeout(function () {
page(function (ctx) {
// handle 404
});
page.start();
}, 0);
It's weird and it should work only if all your middlewares are defined synchronously. Now I have no idea to implement 404 because:
- all unhandled routes should be redirected to they url
- implementation should respect existing API
mb server side 404 can help you?
I think the right solution would be to define a match score on the pattern, similar to how CSS selector specificity and order works. The * selector should have a match score of 0, so it would only trigger if no other pattern matched, regardless of when it was registered. Not sure how route matching works today. How does the system decide between /user and /user/:username when someone visits /user/foo?
what about middlewares that just extend ctx for others like plugins?
I think we could maybe document how to do this sort of thing with middleware.