You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In my actual application, I have a main router that the application uses, then a router for "/api". I tried adding error handling to the api router so that any invalid api paths will be handled with json response vs html for the main application error handler. I found that if I go to /api/invalid, the api middleware wouldn't be used, only the application middleware would be used.
I've reproduced the issue in the example below.
If I make a request to "/a", both routerA and routerB middleware is used since routerB doesn't specify a path.
If I make a request to "/d" which throws an error, it correctly uses the routers error handler.
If I make a request to "/c", it correctly uses the middleware and get handler for routerC.
If I make a request to "/c/a", it correctly uses the get /c/a route along with router middleware before it.
If I make a request to "/c/x", none of the routers middleware is used, only the application middleware is used.
If I make a request to "/e" which does not exist, none of the routers middleware is used, only the application middleware is used.
I would expect that "/c/x" would use the middleware for routerA and routerB which are before the "/c" nested router. I believe it should throw reach the final middleware in that route then be handled by the error handler on routerA.
I would expect that "/e" would use the middleware for routerA and routerB since it is used by the application without a path specified. That's what happens with nested routers like in the request to "/a", it has no matches in routerB but uses routerB middleware since use is called without a path before the route that was matched.
import{Application,Router}from"https://deno.land/x/oak@v10.0.0/mod.ts";constrouterB=newRouter().use(async(ctx,next)=>{console.log("used routerB");awaitnext();}).get("/b",(ctx)=>{ctx.response.body="used get /b";});constrouterC=newRouter().use(async(ctx,next)=>{console.log("used routerB");awaitnext();}).get("/",(ctx)=>{ctx.response.body="used get /c";}).use((ctx)=>{ctx.throw(404);});constrouterA=newRouter().use(async(ctx,next)=>{console.log("used routerA");awaitnext();}).use(async(ctx,next)=>{try{awaitnext();}catch(error){console.error(error);ctx.response.status=error.status;ctx.response.body="used router errorHandler";}}).use(routerB.routes(),routerB.allowedMethods()).use("/c",routerC.routes(),routerC.allowedMethods()).get("/a",(ctx)=>{ctx.response.body="used get /a";}).get("/d",(ctx)=>{ctx.throw(400);}).use((ctx)=>{ctx.throw(404);});constapp=newApplication();app.use(async(ctx,next)=>{console.log("used application");awaitnext();}).use(async(ctx,next)=>{try{awaitnext();}catch(error){console.error(error);ctx.response.status=error.status;ctx.response.body="used application errorHandler";}}).use(routerA.routes(),routerA.allowedMethods()).use((ctx)=>{ctx.throw(404);});console.log("Listening on 8080");awaitapp.listen({port: 8080});
If I'm wrong on this, how do I get different error handling for different routes and ensure it is used when there is not a match? Is there a way to get the api's router middleware to be used even if there is not a match within it?
The text was updated successfully, but these errors were encountered:
I figured out a way to work around the above issue. I added an all handler for the path "/(.*)" as the last path for the router and have it throw a 404 error.
In my actual application, I have a main router that the application uses, then a router for "/api". I tried adding error handling to the api router so that any invalid api paths will be handled with json response vs html for the main application error handler. I found that if I go to /api/invalid, the api middleware wouldn't be used, only the application middleware would be used.
I've reproduced the issue in the example below.
If I make a request to "/a", both routerA and routerB middleware is used since routerB doesn't specify a path.
If I make a request to "/d" which throws an error, it correctly uses the routers error handler.
If I make a request to "/c", it correctly uses the middleware and get handler for routerC.
If I make a request to "/c/a", it correctly uses the get /c/a route along with router middleware before it.
If I make a request to "/c/x", none of the routers middleware is used, only the application middleware is used.
If I make a request to "/e" which does not exist, none of the routers middleware is used, only the application middleware is used.
I would expect that "/c/x" would use the middleware for routerA and routerB which are before the "/c" nested router. I believe it should throw reach the final middleware in that route then be handled by the error handler on routerA.
I would expect that "/e" would use the middleware for routerA and routerB since it is used by the application without a path specified. That's what happens with nested routers like in the request to "/a", it has no matches in routerB but uses routerB middleware since use is called without a path before the route that was matched.
If I'm wrong on this, how do I get different error handling for different routes and ensure it is used when there is not a match? Is there a way to get the api's router middleware to be used even if there is not a match within it?
The text was updated successfully, but these errors were encountered: