ZijianHe / koa-router

Router middleware for koa.
MIT License
4.85k stars 406 forks source link

Middleware prevents async route and return 404 #476

Closed jinbe0 closed 6 years ago

jinbe0 commented 6 years ago

Node.js: 10.9.0 npm: 6.2.0 koa-router: 7.4.0 koa: 2.5.2

In the below example, simple koa server is running on localhost:2000. Expected behavior at http://localhost:2000/heavy-task is that returning "result of a heavy task" with 200 OK after 1 second. Actual behavior is that returning 404 Not Found. This problem occurs when a shared middleware (in the below example, User Middleware) exists and a matched route (in the below example, /heavy-task) has async callback.

If there's no shared middleware, or if callback function of the route is not async, it works as expected. In all cases, http://localhost:2000/ responds "hello Alice". Is this a bug?

import Koa from "koa";
import Router from "koa-router";

const router = new Router();
router.use((context, next) => {
    /* User Middleware */
    context.state.user = {
        name: "Alice",
        mail: "alice@example.com",
    };
    next();
});
router.get("/", (context) => context.body = `hello ${context.state.user.name}`);
router.get("/heavy-task", async (context, next) => {
    await sleep(1000);
    context.body = "result of a heavy task";
    next();
});

const app = new Koa();
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(2000);

function sleep(ms) {
    return new Promise((res) => {
        setTimeout(res, ms);
    });
}
jbielick commented 6 years ago

You must return or await next. Just calling next doesn’t allow Koa to await downstream middleware. Does return next(); fix your issue?

jinbe0 commented 6 years ago

Solved! ty

kenmorechalfant commented 5 years ago

You must return or await next

Sorry to revive old issue but this just fixed my issue, @jbielick

But, you know... I'm pretty sure this is not mentioned anywhere in the docs or the middleware guide. Cost me at least an hour of time just now 😭

fl0w commented 5 years ago

@kenmorechalfant This isn't a library quirk, but how promises and thus async-await work in javascript.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

kenmorechalfant commented 5 years ago

@fl0w I understand. It's just that, being new to Koa, it wasn't obvious to me how it all works under the hood. It would be helpful if the docs just gave a tip about it. From my experience with Express, middleware just has to call next(), not return it. It's just a gotcha for people switching to Koa.

fl0w commented 5 years ago

Yea I understand navigating new landscape can be rough, but there are resources. From koajs.com there's the guide which in turn points to my-middleware-is-not-called. Seek and ye shall find! Good luck.