Skip to content

Commit

Permalink
fix(cli): catch stream errors on repository server
Browse files Browse the repository at this point in the history
  • Loading branch information
juanrgm committed Feb 21, 2024
1 parent f89e837 commit 12c8f19
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/curvy-lions-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@datatruck/cli": patch
---

Catch stream errors on repository server
35 changes: 21 additions & 14 deletions packages/cli/src/utils/datatruck/repository-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LocalFs } from "../virtual-fs";
import { createReadStream, createWriteStream } from "fs";
import { stat } from "fs/promises";
import { IncomingMessage, createServer } from "http";
import { pipeline } from "stream/promises";

type User = {
enabled?: boolean;
Expand Down Expand Up @@ -111,6 +112,10 @@ export function createDatatruckRepositoryServer(
) {
return createServer(async (req, res) => {
const url = req.url || "";
let requestError: Error | undefined;
let responseError: Error | undefined;
req.on("error", (error) => (requestError = error));
res.on("error", (error) => (responseError = error));
try {
if (url === "/" || url === "/favicon.ico") return;
const { repository, action, params } = parseUrl(url);
Expand All @@ -137,25 +142,14 @@ export function createDatatruckRepositoryServer(
const [target] = params;
const path = fs.resolvePath(target);
const file = createWriteStream(path);
req.pipe(file);
await new Promise<void>((resolve, reject) => {
req.on("error", reject);
file.on("error", reject);
file.on("close", resolve);
});
await pipeline(req, file);
} else if (action === "download") {
const [target] = params;
const path = fs.resolvePath(target);
const file = createReadStream(path);
const fileStat = await stat(path);
res.setHeader("Content-Length", fileStat.size);
file.pipe(res);
await new Promise<void>((resolve, reject) => {
req.on("error", reject);
file.on("error", reject);
res.on("error", reject);
res.on("close", resolve);
});
await pipeline(file, res, { end: false });
} else if (action === "writeFile") {
const data = await readRequestData(req);
const [target] = params;
Expand All @@ -174,7 +168,20 @@ export function createDatatruckRepositoryServer(
}
if (!res.headersSent) res.writeHead(500, (error as Error).message);
} finally {
res.end();
if (requestError) {
logJson("repository-server", "request error", { url });
console.error(requestError);
}
if (responseError) {
logJson("repository-server", "response error", { url });
console.error(responseError);
}

if (requestError || responseError) {
res.destroy();
} else {
res.end();
}
}
});
}

0 comments on commit 12c8f19

Please sign in to comment.