Skip to content

Commit

Permalink
chore: logs for express body parser (#577)
Browse files Browse the repository at this point in the history
  • Loading branch information
juliusmarminge authored Jan 26, 2024
1 parent 9a0bf1e commit 8a9878f
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
8 changes: 8 additions & 0 deletions .changeset/shy-hounds-train.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"uploadthing": patch
---

chore(express): add logs for express body parser

Enables easier debugging for a common issue Express users has had when registed other middlewares before UploadThing that processes the body in an incompatible way.
These logs should help track down these cases more easily
5 changes: 4 additions & 1 deletion packages/uploadthing/src/express.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
buildRequestHandler,
} from "./internal/handler";
import { incompatibleNodeGuard } from "./internal/incompat-node-guard";
import { initLogger } from "./internal/logger";
import { initLogger, logger } from "./internal/logger";
import { getPostBody } from "./internal/node-http/getBody";
import { toWebRequest } from "./internal/node-http/toWebRequest";
import type { FileRouter } from "./internal/types";
Expand Down Expand Up @@ -47,6 +47,9 @@ export const createRouteHandler = <TRouter extends FileRouter>(
const bodyResult = await getPostBody({ req });

if (!bodyResult.ok) {
logger.error(
"Error parsing body. UploadThing expects a raw JSON body, make sure any body-parsing middlewares are registered after uploadthing.",
);
res.status(400);
res.setHeader("x-uploadthing-version", UPLOADTHING_VERSION);
res.send(
Expand Down
23 changes: 21 additions & 2 deletions packages/uploadthing/src/internal/node-http/getBody.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { IncomingMessage } from "node:http";

import { UploadThingError } from "@uploadthing/shared";

import { logger } from "../logger";

export type BodyResult =
| {
ok: true;
Expand All @@ -18,9 +20,10 @@ export async function getPostBody(opts: {
const { req, maxBodySize = Infinity } = opts;
return new Promise((resolve) => {
if ("body" in req) {
const isJsonType = req.headers["content-type"] === "application/json";
const contentType = req.headers["content-type"];

if (!isJsonType) {
if (contentType !== "application/json") {
logger.error("Expected JSON content type, got:", contentType);
resolve({
ok: false,
error: new UploadThingError({
Expand All @@ -32,6 +35,10 @@ export async function getPostBody(opts: {
}

if (typeof req.body !== "object") {
logger.error(
"Expected body to be of type 'object', got:",
typeof req.body,
);
resolve({
ok: false,
error: new UploadThingError({
Expand All @@ -42,6 +49,7 @@ export async function getPostBody(opts: {
return;
}

logger.debug("Body parsed successfully.", req.body);
resolve({
ok: true,
data: req.body,
Expand All @@ -54,6 +62,13 @@ export async function getPostBody(opts: {
body += data;
hasBody = true;
if (body.length > maxBodySize) {
logger.error(
"Body too large, max size is",
maxBodySize,
"bytes but received",
body.length,
"bytes",
);
resolve({
ok: false,
error: new UploadThingError({
Expand All @@ -67,18 +82,22 @@ export async function getPostBody(opts: {
req.on("end", () => {
let parsedBody: unknown;
try {
logger.debug("Finished reading body, parsing as JSON", body);
parsedBody = JSON.parse(body);
} catch (e) {
logger.error("Error parsing JSON:", body);
resolve({
ok: false,
error: new UploadThingError({
code: "BAD_REQUEST",
message: "INVALID_JSON",
cause: e,
}),
});
return;
}

logger.debug("Body parsed successfully.", parsedBody);
resolve({
ok: true,
data: hasBody ? parsedBody : undefined,
Expand Down

1 comment on commit 8a9878f

@vercel
Copy link

@vercel vercel bot commented on 8a9878f Jan 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.