Skip to content

Commit 40a7c11

Browse files
committed
node/routes: Fix error handling
We should always send HTML if the user agent expects it. If they do not, they should clearly indicate such via the Accept header. Closes #2297
1 parent 7afa689 commit 40a7c11

File tree

2 files changed

+13
-9
lines changed

2 files changed

+13
-9
lines changed

src/node/routes/domainProxy.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ router.all("*", (req, res, next) => {
4848
// Assume anything that explicitly accepts text/html is a user browsing a
4949
// page (as opposed to an xhr request). Don't use `req.accepts()` since
5050
// *every* request that I've seen (in Firefox and Chromium at least)
51-
// includes `*/*` making it always truthy.
52-
if (typeof req.headers.accepts === "string" && req.headers.accepts.split(",").includes("text/html")) {
51+
// includes `*/*` making it always truthy. Even for css/javascript.
52+
if (req.headers.accept && req.headers.accept.includes("text/html")) {
5353
// Let the login through.
5454
if (/\/login\/?/.test(req.path)) {
5555
return next()

src/node/routes/index.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -125,20 +125,19 @@ export const register = async (
125125
throw new HttpError("Not Found", HttpCode.NotFound)
126126
})
127127

128-
const errorHandler: express.ErrorRequestHandler = async (err, req, res) => {
128+
const errorHandler: express.ErrorRequestHandler = async (err, req, res, next) => {
129129
if (err.code === "ENOENT" || err.code === "EISDIR") {
130130
err.status = HttpCode.NotFound
131131
}
132132

133133
const status = err.status ?? err.statusCode ?? 500
134134
res.status(status)
135135

136-
if (req.accepts("application/json")) {
137-
res.json({
138-
error: err.message,
139-
...(err.details || {}),
140-
})
141-
} else {
136+
// Assume anything that explicitly accepts text/html is a user browsing a
137+
// page (as opposed to an xhr request). Don't use `req.accepts()` since
138+
// *every* request that I've seen (in Firefox and Chromium at least)
139+
// includes `*/*` making it always truthy. Even for css/javascript.
140+
if (req.headers.accept && req.headers.accept.includes("text/html")) {
142141
const resourcePath = path.resolve(rootPath, "src/browser/pages/error.html")
143142
res.set("Content-Type", getMediaMime(resourcePath))
144143
const content = await fs.readFile(resourcePath, "utf8")
@@ -148,6 +147,11 @@ export const register = async (
148147
.replace(/{{ERROR_HEADER}}/g, status)
149148
.replace(/{{ERROR_BODY}}/g, err.message),
150149
)
150+
} else {
151+
res.json({
152+
error: err.message,
153+
...(err.details || {}),
154+
})
151155
}
152156
}
153157

0 commit comments

Comments
 (0)