Because you mentioned that this problem occurs in multiple environments (Deno, Bun, Insomnia, etc.), it seems likely that the response is not valid, but some parsers handle it more gracefully (e.g. Chrome, Node, etc.). Note: I can't verify this without seeing the exact response that you are — and you haven't included the binary response data in the question.
In any case, you can create an abstraction to gracefully handle an unexpected end of file scenario during parsing — you can check that the collected data meets your criteria in your exception-handling code, and recover at that point if things seem ok. Here's an example that I tested in Deno and Node:
main.mjs
:
async function parseHtmlBody(response) {
const decoder = new TextDecoder();
let html = "";
try {
for await (const u8Arr of response.body) {
const str = decoder.decode(u8Arr, { stream: true });
html += str;
}
return html;
} catch (cause) {
if (
// The exception is an error:
cause instanceof Error
// And it includes the expected message text:
&& cause.message.toLowerCase().includes("unexpected end of file")
// And it looks like the end of the document was received:
&& html.trimEnd().endsWith("</html>")
) return html;
// Else, rethrow:
throw cause;
}
}
async function main() {
// The URL in your question details:
const url = "https://www.uvic.ca/cas/login";
const response = await fetch(url, { redirect: "follow" });
const html = await parseHtmlBody(response);
// Print the beginning and end of the HTML document and its length:
console.log(html.slice(0, 100));
console.log("…");
console.log(html.slice(-100));
console.log("Total length:", html.length);
}
main();
In the terminal:
% node --version
v18.16.1
% node main.mjs
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8" /><meta name="viewport" content="w
…
t src="https://kit.fontawesome.com/32795de2d2.js" crossorigin="anonymous"></script>
</body>
</html>
Total length: 7236
% deno --version
deno 1.35.0 (release, aarch64-apple-darwin)
v8 11.6.189.7
typescript 5.1.6
% deno run --allow-net main.mjs
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8" /><meta name="viewport" content="w
…
t src="https://kit.fontawesome.com/32795de2d2.js" crossorigin="anonymous"></script>
</body>
</html>
Total length: 7236
Both outputs look the same. You can modify the code above to meet your needs.