koajs / router

Router middleware for Koa. Maintained by @forwardemail and @ladjs.
MIT License
849 stars 174 forks source link

Receive 404 with busyboy #138

Closed budarin closed 2 years ago

budarin commented 2 years ago

node.js version: 16.9.0

yarn version: 1.22.15

@koa/router version: 10.1.1

koa version: 2.13.4

Code sample:

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

import { appOnError } from "./appOnError.mjs";
import { uploadFile } from "./uploadFile.mjs";
import { renderApp } from "./renderApp.mjs";

const router = new Router();
export const app = new Koa();

app.on("error", appOnError);

router.post("/upload", uploadFile);
router.get("/", renderApp);

app.use(router.routes());
app.use(router.allowedMethods());

app.listen(4500);

Here is a simple uploadFile code

import Busboy from "busboy";

export const uploadFile = async (ctx, next) => {
const busboy = new Busboy({
    headers: { "content-type": ctx.get("content-type") },
  });

  // busboy initialization
  busboy.on('...', (...) => {...});

  busboy.on("finish", () => {
    ctx.set("Connection", "close");
    ctx.status = 200;
    ctx.body = "Ok";
  });

  ctx.req.pipe(busboy);
}

Expected Behavior:

Expected client have received "Ok" text with 200 status

Actual Behavior:

Have 404 error while busboy did its job - save files in stream and fired finish event properly

Additional steps, HTTP request details, or to reproduce the behavior or a test case:

Here is the demo project

budarin commented 2 years ago

Solved! I must use Promise to wait for busboy as

import Busboy from "busboy";

export const uploadFile = async (ctx, next) => {
  const p = new Promise((resolve, reject) => {

    const busboy = new Busboy({
      headers: { "content-type": ctx.get("content-type") },
    });

    // busboy initialization
    busboy.on('...', (...) => {...});

    busboy.on("finish", () => {
      ctx.set("Connection", "close");
      ctx.status = 200;
      ctx.body = "Ok";
    });

    ctx.req.pipe(busboy);
 });

 await p.then(() => {
      ctx.set("Connection", "close");
      ctx.status = 200;
      ctx.body = { result: "Ok" };
    })
    .catch((error) => {
      ctx.status = 500;
      ctx.body = error.message;
    });
}