koajs / koa-body

koa body parser middleware
MIT License
947 stars 131 forks source link

Versi 6.x : Cannot destructure property 'XXX' of 'ctx.request.body' as it is undefined. #218

Open zgramming opened 1 year ago

zgramming commented 1 year ago

Describe the bug

Node.js version: v18.9.1

OS version: Windows 11 Home Version 22H2

Description:

Actual behavior

Destructure property undefined throw error

image

Expected behavior

It's use version 5

Destructure property undefined not throw error

image

Code to reproduce

 public static async Testing(ctx: ParameterizedContext, next: Next) {
    try {
      const { id, user_id, template_pdf_id } = ctx.request.body;

      ctx.status = 200;
      return (ctx.body = {
        message: "Berhasil mengupdate template PDF",
        // data: upsert,
      });
    } catch (error: any) {
      console.log({ error: error });
      ctx.status = error.code ?? 500;
      return (ctx.body = {
        success: false,
        message: error?.message ?? "Unknown Message Error",
      });
    }
  }

Checklist

TheDadi commented 1 year ago

@zgramming can you please share:

  1. request as curl
  2. configuration of the middleware

Thx

zgramming commented 1 year ago

@TheDadi

  1. curl

    curl --location --request POST 'http://localhost:6969/cv/preview/testing' 
  2. config middleware

import Koa from "koa";
import KoaBody from "koa-body";
import Json from "koa-json";
import Logger from "koa-logger";
import passport from "koa-passport";
import session from "koa-session";
import Serve from "koa-static";

import cors from "@koa/cors";

import router from "./router";

const app = new Koa();

require("dotenv").config();
require("./utils/passport");

/// Passport initialize
app.keys = [process.env.KOA_SESSION_SECRET ?? ""];
app.use(session({}, app));
app.use(passport.initialize());
app.use(passport.session());
app.use(
  KoaBody({
    multipart: true,
  })
);

app.use(cors());
app.use(Json());
app.use(Logger());

/// Make folder file accessible via url
app.use(Serve("./public"));

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

app.listen(process.env.PORT, () => {
  console.log("Koa server is started on " + process.env.PORT);
});
TheDadi commented 1 year ago

@zgramming

Your not passing any content-type header and no data, that means it parses nothing at all. Version 5 used to give you back an empty object which v6 is not anymore.

isJson, isText, isUrlencoded, isMultipart are all falsy

@MarkHerhold should we add back this behavior since we do the same if the request method does not match parsedMethods? I created a pr that changes back the empty object behavior. Or should we remove the empty object also for non matching parsedMethods that the body always gets undefined if it matches neither parsedMethods and no content-type

TheDadi commented 1 year ago

@zgramming

The behavior for version 6.x is different, but in my opinion you should anyways do some validations on the body before destructuring and give back a http 400 if it doesn't match.

zgramming commented 1 year ago

@TheDadi IMHO I think revert back old behaviour version 5 good option, because maybe we can have some request can be optional/undefined 😀.

tiagojsag commented 1 year ago

Hey everyone,

I recently ran into this issue, and was about halfway into fixing it on my fork when I found this issue+PR. I have extended the previous proposed solution by adding a new config option, that would default to the "new" behavior (undefined body), while allowing support for the old behavior (empty object body).

Restoring the old behavior would be simpler, ofc, but since this is already live, someone might be relying on it, so having a config option adds complexity but should also keep everyone happy.

Kudos to @TheDadi for the original PR, whose code I copy-pasted into my commit, and extended.

Let me know your thoughts.

TheDadi commented 1 year ago

@MarkHerhold Since you seem very busy at the moment, would it be possible to talk about how to get a maintainer of this repo and help you out?

TheDadi commented 1 year ago

@MarkHerhold ping ☝️