Open
Description
Enountered this most recently in the context of #329, but I have seen this before -- where an internal error is thrown, the 500 with the error message is sent to the client, but not logged.
So there is no way to know from looking at logs that this error occured -- even when attempting to try-catch the event handler.
Can't find a more straightforward repro for now, but executing the function below results in this being received by the client:
* upload completely sent off: 36 bytes
< HTTP/1.1 500 Internal Server Error
< content-length: 66
< content-type: application/json; charset=utf-8
< date: Fri, 07 Feb 2025 20:11:55 GMT
<
* Connection #0 to host localhost left intact
{"status":500,"error":"attempting to access detached ArrayBuffer"}%
Expected behavior: I should be able to catch this error and handle it gracefully.
// For AutoRouter documentation refer to https://itty.dev/itty-router/routers/autorouter
import { AutoRouter } from 'itty-router';
let router = AutoRouter();
router
.post('/api/tee', async (req) => {
console.log('[tee]: received request to tee');
const [forwardStream, logStream] = req.body!.tee();
const forwardRequest = new Request('http://localhost:3000/api/forwarded', { body: forwardStream, method: req.method });
const response = await fetch(forwardRequest);
await logRequestBody(logStream);
return response;
})
.post('/api/forwarded', async (req) => {
console.log(`[forwarded]: ${await req.text()}`)
return new Response('Successfully forwarded', { status: 200 })
})
/**
* Reads the tee’d stream and logs its content.
*/
async function logRequestBody(stream: any) {
const reader = stream.getReader();
const chunks = [];
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
}
const fullArray = concatChunks(chunks);
// Decode the Uint8Array into a UTF-8 string.
const text = new TextDecoder("utf-8").decode(fullArray);
console.log(`[tee]: Logged request body: ${text}`);
}
/**
* Helper function that concatenates an array of Uint8Arrays into a single Uint8Array.
*/
function concatChunks(chunks: any) {
const totalLength = chunks.reduce((sum: any, chunk: any) => sum + chunk.length, 0);
const result = new Uint8Array(totalLength);
let offset = 0;
for (const chunk of chunks) {
result.set(chunk, offset);
offset += chunk.length;
}
return result;
}
//@ts-ignore
addEventListener('fetch', async (event: FetchEvent) => {
try {
event.respondWith(router.fetch(event.request));
} catch (e: any) {
console.error(`[api]: Error in API: ${e.toString()}`);
}
});
Metadata
Metadata
Assignees
Labels
No labels