mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 17:54:32 +00:00
fix(infra): avoid req.destroy(err) in request body limiters
This commit is contained in:
@@ -13,11 +13,26 @@ function createMockRequest(params: {
|
||||
headers?: Record<string, string>;
|
||||
emitEnd?: boolean;
|
||||
}): IncomingMessage {
|
||||
const req = new EventEmitter() as IncomingMessage & { destroyed?: boolean; destroy: () => void };
|
||||
const req = new EventEmitter() as IncomingMessage & {
|
||||
destroyed?: boolean;
|
||||
destroy: (error?: Error) => void;
|
||||
__unhandledDestroyError?: unknown;
|
||||
};
|
||||
req.destroyed = false;
|
||||
req.headers = params.headers ?? {};
|
||||
req.destroy = () => {
|
||||
req.destroy = (error?: Error) => {
|
||||
req.destroyed = true;
|
||||
if (error) {
|
||||
// Simulate Node's async 'error' emission on destroy(err). If no listener is
|
||||
// present at that time, EventEmitter throws; capture that as "unhandled".
|
||||
queueMicrotask(() => {
|
||||
try {
|
||||
req.emit("error", error);
|
||||
} catch (err) {
|
||||
req.__unhandledDestroyError = err;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (params.chunks) {
|
||||
@@ -66,6 +81,7 @@ describe("http body limits", () => {
|
||||
await expect(readRequestBodyWithLimit(req, { maxBytes: 64 })).rejects.toMatchObject({
|
||||
message: "PayloadTooLarge",
|
||||
});
|
||||
expect(req.__unhandledDestroyError).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns json parse error when body is invalid", async () => {
|
||||
@@ -104,6 +120,7 @@ describe("http body limits", () => {
|
||||
expect(guard.code()).toBe("PAYLOAD_TOO_LARGE");
|
||||
expect(res.statusCode).toBe(413);
|
||||
expect(res.body).toBe("Payload too large");
|
||||
expect(req.__unhandledDestroyError).toBeUndefined();
|
||||
});
|
||||
|
||||
it("timeout surfaces typed error", async () => {
|
||||
@@ -112,5 +129,19 @@ describe("http body limits", () => {
|
||||
await expect(promise).rejects.toSatisfy((error: unknown) =>
|
||||
isRequestBodyLimitError(error, "REQUEST_BODY_TIMEOUT"),
|
||||
);
|
||||
expect(req.__unhandledDestroyError).toBeUndefined();
|
||||
});
|
||||
|
||||
it("declared oversized content-length does not emit unhandled error", async () => {
|
||||
const req = createMockRequest({
|
||||
headers: { "content-length": "9999" },
|
||||
emitEnd: false,
|
||||
});
|
||||
await expect(readRequestBodyWithLimit(req, { maxBytes: 128 })).rejects.toMatchObject({
|
||||
message: "PayloadTooLarge",
|
||||
});
|
||||
// Wait a tick for any async destroy(err) emission.
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
expect(req.__unhandledDestroyError).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user