vibe-gx 1.0.5 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-gx",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "A lightweight, regex-based Node.js web framework built for speed and simplicity.",
5
5
  "type": "module",
6
6
  "main": "vibe.js",
@@ -140,21 +140,34 @@ export async function runIntercept(intercept, req, res, isRoute = true) {
140
140
  */
141
141
  export function handleError(error, req, res) {
142
142
  const isDev = process.env.NODE_ENV !== "production";
143
+ const message = error.message || "Unknown error";
143
144
 
144
145
  // Log error (full stack in dev, message only in production)
145
146
  if (isDev) {
146
147
  console.error("[VIBE ERROR]:", error);
147
148
  } else {
148
- console.error("[VIBE ERROR]:", error.message || "Unknown error");
149
+ console.error("[VIBE ERROR]:", message);
149
150
  }
150
151
 
151
152
  if (!res.headersSent) {
152
- res.writeHead(500, { "content-type": "application/json" });
153
+ // Determine status code based on error type
154
+ let statusCode = 500;
155
+ let errorType = "Internal Server Error";
156
+
157
+ if (message.includes("exceeds max size")) {
158
+ statusCode = 413;
159
+ errorType = "Payload Too Large";
160
+ } else if (message.includes("not allowed")) {
161
+ statusCode = 415;
162
+ errorType = "Unsupported Media Type";
163
+ }
164
+
165
+ res.writeHead(statusCode, { "content-type": "application/json" });
153
166
 
154
167
  // Only expose error details in development
155
168
  const responseBody = isDev
156
- ? { error: "Internal Server Error", message: error.message }
157
- : { error: "Internal Server Error" };
169
+ ? { error: errorType, message }
170
+ : { error: errorType };
158
171
 
159
172
  res.end(JSON.stringify(responseBody));
160
173
  }
@@ -56,9 +56,22 @@ function parseMultipart(req, res, media, options, resolve, reject) {
56
56
  const streaming = media.streaming === true;
57
57
  let pendingWrites = 0;
58
58
  let busboyFinished = false;
59
+ let alreadyRejected = false;
59
60
 
60
- // Helper to check if we're done
61
+ // Helper to reject immediately (for errors that shouldn't wait)
62
+ const rejectNow = (err) => {
63
+ if (alreadyRejected) return;
64
+ alreadyRejected = true;
65
+ // Unpipe to stop processing more data
66
+ req.unpipe(bb);
67
+ // Drain the request to prevent hanging
68
+ req.resume();
69
+ reject(err);
70
+ };
71
+
72
+ // Helper to check if we're done (for normal completion)
61
73
  const checkComplete = () => {
74
+ if (alreadyRejected) return;
62
75
  if (busboyFinished && pendingWrites === 0) {
63
76
  if (fileError) {
64
77
  reject(fileError);
@@ -97,10 +110,12 @@ function parseMultipart(req, res, media, options, resolve, reject) {
97
110
  return allowed === mimeType;
98
111
  });
99
112
  if (!isAllowed) {
100
- fileError = new Error(
101
- `File type '${mimeType}' not allowed. Allowed: ${media.allowedTypes.join(", ")}`,
113
+ file.resume();
114
+ return rejectNow(
115
+ new Error(
116
+ `File type '${mimeType}' not allowed. Allowed: ${media.allowedTypes.join(", ")}`,
117
+ ),
102
118
  );
103
- return file.resume();
104
119
  }
105
120
  }
106
121
 
@@ -156,16 +171,18 @@ function parseMultipart(req, res, media, options, resolve, reject) {
156
171
  // Handle file size limit exceeded
157
172
  file.on("limit", () => {
158
173
  truncated = true;
159
- fileError = new Error(
174
+ const err = new Error(
160
175
  `File '${filename}' exceeds max size of ${media.maxSize || 10 * 1024 * 1024} bytes`,
161
176
  );
162
177
  file.unpipe(writeStream);
163
178
  writeStream.end();
164
- // Clean up partial file
179
+ file.resume();
180
+ // Clean up partial file and reject immediately
165
181
  fs.unlink(filePath, () => {
166
182
  pendingWrites--;
167
- checkComplete();
168
183
  });
184
+ // Reject NOW - don't wait for busboy to finish
185
+ rejectNow(err);
169
186
  });
170
187
 
171
188
  file.on("error", (err) => {