refactor(telegram-tests): share webhook settlement helper
This commit is contained in:
parent
1ff10690e7
commit
e1ca5d9cc4
@ -40,6 +40,35 @@ function collectResponseBody(
|
||||
});
|
||||
}
|
||||
|
||||
function createSingleSettlement<T>(params: {
|
||||
resolve: (value: T) => void;
|
||||
reject: (error: unknown) => void;
|
||||
clear: () => void;
|
||||
}) {
|
||||
let settled = false;
|
||||
return {
|
||||
isSettled() {
|
||||
return settled;
|
||||
},
|
||||
resolve(value: T) {
|
||||
if (settled) {
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
params.clear();
|
||||
params.resolve(value);
|
||||
},
|
||||
reject(error: unknown) {
|
||||
if (settled) {
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
params.clear();
|
||||
params.reject(error);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
vi.mock("grammy", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("grammy")>();
|
||||
return {
|
||||
@ -96,23 +125,11 @@ async function postWebhookHeadersOnly(params: {
|
||||
timeoutMs?: number;
|
||||
}): Promise<{ statusCode: number; body: string }> {
|
||||
return await new Promise((resolve, reject) => {
|
||||
let settled = false;
|
||||
const finishResolve = (value: { statusCode: number; body: string }) => {
|
||||
if (settled) {
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
clearTimeout(timeout);
|
||||
resolve(value);
|
||||
};
|
||||
const finishReject = (error: unknown) => {
|
||||
if (settled) {
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
clearTimeout(timeout);
|
||||
reject(error);
|
||||
};
|
||||
const settle = createSingleSettlement({
|
||||
resolve,
|
||||
reject,
|
||||
clear: () => clearTimeout(timeout),
|
||||
});
|
||||
|
||||
const req = request(
|
||||
{
|
||||
@ -128,7 +145,7 @@ async function postWebhookHeadersOnly(params: {
|
||||
},
|
||||
(res) => {
|
||||
collectResponseBody(res, (payload) => {
|
||||
finishResolve(payload);
|
||||
settle.resolve(payload);
|
||||
req.destroy();
|
||||
});
|
||||
},
|
||||
@ -138,14 +155,14 @@ async function postWebhookHeadersOnly(params: {
|
||||
req.destroy(
|
||||
new Error(`webhook header-only post timed out after ${params.timeoutMs ?? 5_000}ms`),
|
||||
);
|
||||
finishReject(new Error("timed out waiting for webhook response"));
|
||||
settle.reject(new Error("timed out waiting for webhook response"));
|
||||
}, params.timeoutMs ?? 5_000);
|
||||
|
||||
req.on("error", (error) => {
|
||||
if (settled && (error as NodeJS.ErrnoException).code === "ECONNRESET") {
|
||||
if (settle.isSettled() && (error as NodeJS.ErrnoException).code === "ECONNRESET") {
|
||||
return;
|
||||
}
|
||||
finishReject(error);
|
||||
settle.reject(error);
|
||||
});
|
||||
|
||||
req.flushHeaders();
|
||||
@ -173,23 +190,11 @@ async function postWebhookPayloadWithChunkPlan(params: {
|
||||
let bytesQueued = 0;
|
||||
let chunksQueued = 0;
|
||||
let phase: "writing" | "awaiting-response" = "writing";
|
||||
let settled = false;
|
||||
const finishResolve = (value: { statusCode: number; body: string }) => {
|
||||
if (settled) {
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
clearTimeout(timeout);
|
||||
resolve(value);
|
||||
};
|
||||
const finishReject = (error: unknown) => {
|
||||
if (settled) {
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
clearTimeout(timeout);
|
||||
reject(error);
|
||||
};
|
||||
const settle = createSingleSettlement({
|
||||
resolve,
|
||||
reject,
|
||||
clear: () => clearTimeout(timeout),
|
||||
});
|
||||
|
||||
const req = request(
|
||||
{
|
||||
@ -204,12 +209,12 @@ async function postWebhookPayloadWithChunkPlan(params: {
|
||||
},
|
||||
},
|
||||
(res) => {
|
||||
collectResponseBody(res, finishResolve);
|
||||
collectResponseBody(res, settle.resolve);
|
||||
},
|
||||
);
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
finishReject(
|
||||
settle.reject(
|
||||
new Error(
|
||||
`webhook post timed out after ${params.timeoutMs ?? 15_000}ms (phase=${phase}, bytesQueued=${bytesQueued}, chunksQueued=${chunksQueued}, totalBytes=${payloadBuffer.length})`,
|
||||
),
|
||||
@ -218,7 +223,7 @@ async function postWebhookPayloadWithChunkPlan(params: {
|
||||
}, params.timeoutMs ?? 15_000);
|
||||
|
||||
req.on("error", (error) => {
|
||||
finishReject(error);
|
||||
settle.reject(error);
|
||||
});
|
||||
|
||||
const writeAll = async () => {
|
||||
@ -251,7 +256,7 @@ async function postWebhookPayloadWithChunkPlan(params: {
|
||||
};
|
||||
|
||||
void writeAll().catch((error) => {
|
||||
finishReject(error);
|
||||
settle.reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user