Skip to content

Commit

Permalink
fix: error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Jul 17, 2024
1 parent c2d8f13 commit 21302d1
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 19 deletions.
46 changes: 27 additions & 19 deletions src/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,26 @@ function wrapper(context) {
finish(res, document);
}

/**
* @param {NodeJS.ErrnoException} error
*/
function errorHandler(error) {
switch (error.code) {
case "ENAMETOOLONG":
case "ENOENT":
case "ENOTDIR":
sendError(404, {
modifyResponseData: context.options.modifyResponseData,
});
break;
default:
sendError(500, {
modifyResponseData: context.options.modifyResponseData,
});
break;
}
}

function isConditionalGET() {
return (
getRequestHeader(req, "if-match") ||
Expand Down Expand Up @@ -585,8 +605,10 @@ function wrapper(context) {

value = result.bufferOrStream;
({ bufferOrStream, byteLength } = result);
} catch (_err) {
// Ignore here
} catch (error) {
errorHandler(/** @type {NodeJS.ErrnoException} */ (error));
await goNext();
return;
}
}

Expand Down Expand Up @@ -708,7 +730,8 @@ function wrapper(context) {
start,
end,
));
} catch (_ignoreError) {
} catch (error) {
errorHandler(/** @type {NodeJS.ErrnoException} */ (error));
await goNext();
return;
}
Expand Down Expand Up @@ -764,22 +787,7 @@ function wrapper(context) {
(bufferOrStream).on("error", (error) => {
// clean up stream early
cleanup();

// Handle Error
switch (/** @type {NodeJS.ErrnoException} */ (error).code) {
case "ENAMETOOLONG":
case "ENOENT":
case "ENOTDIR":
sendError(404, {
modifyResponseData: context.options.modifyResponseData,
});
break;
default:
sendError(500, {
modifyResponseData: context.options.modifyResponseData,
});
break;
}
errorHandler(error);
});

pipe(res, /** @type {ReadStream} */ (bufferOrStream));
Expand Down
132 changes: 132 additions & 0 deletions test/middleware.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3046,6 +3046,138 @@ describe.each([
expect(response.body).toEqual({});
});
});

describe("should handle custom fs errors and response 500 code without `fs.createReadStream`", () => {
let compiler;

const outputPath = path.resolve(
__dirname,
"./outputs/basic-test-errors-500",
);

beforeAll(async () => {
compiler = getCompiler({
...webpackConfig,
output: {
filename: "bundle.js",
path: outputPath,
},
});

[server, req, instance] = await frameworkFactory(
name,
framework,
compiler,
);

instance.context.outputFileSystem.mkdirSync(outputPath, {
recursive: true,
});
instance.context.outputFileSystem.writeFileSync(
path.resolve(outputPath, "image.svg"),
"svg image",
);

instance.context.outputFileSystem.readFileSync =
function readFileSync() {
throw new Error("test");
};
instance.context.outputFileSystem.createReadStream = null;
});

afterAll(async () => {
await close(server, instance);
});

it('should return the "500" code for the "GET" request to the "image.svg" file', async () => {
const response = await req.get("/image.svg");

expect(response.statusCode).toEqual(500);
expect(response.headers["content-type"]).toEqual(
"text/html; charset=utf-8",
);
expect(response.text).toEqual(
"<!DOCTYPE html>\n" +
'<html lang="en">\n' +
"<head>\n" +
'<meta charset="utf-8">\n' +
"<title>Error</title>\n" +
"</head>\n" +
"<body>\n" +
"<pre>Internal Server Error</pre>\n" +
"</body>\n" +
"</html>",
);
});
});

describe("should handle known fs errors and response 404 code", () => {
let compiler;

const outputPath = path.resolve(
__dirname,
"./outputs/basic-test-errors-404",
);

beforeAll(async () => {
compiler = getCompiler({
...webpackConfig,
output: {
filename: "bundle.js",
path: outputPath,
},
});

[server, req, instance] = await frameworkFactory(
name,
framework,
compiler,
);

instance.context.outputFileSystem.mkdirSync(outputPath, {
recursive: true,
});
instance.context.outputFileSystem.writeFileSync(
path.resolve(outputPath, "image.svg"),
"svg image",
);

instance.context.outputFileSystem.readFileSync =
function readFileSync() {
const error = new Error("test");

error.code = "ENAMETOOLONG";

throw error;
};
instance.context.outputFileSystem.createReadStream = null;
});

afterAll(async () => {
await close(server, instance);
});

it('should return the "404" code for the "GET" request to the "image.svg" file', async () => {
const response = await req.get("/image.svg");

expect(response.statusCode).toEqual(404);
expect(response.headers["content-type"]).toEqual(
"text/html; charset=utf-8",
);
expect(response.text).toEqual(
"<!DOCTYPE html>\n" +
'<html lang="en">\n' +
"<head>\n" +
'<meta charset="utf-8">\n' +
"<title>Error</title>\n" +
"</head>\n" +
"<body>\n" +
"<pre>Not Found</pre>\n" +
"</body>\n" +
"</html>",
);
});
});
});

describe("mimeTypes option", () => {
Expand Down

0 comments on commit 21302d1

Please sign in to comment.