forked from coder/code-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patherrors.ts
45 lines (41 loc) · 1.66 KB
/
errors.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import { logger } from "@coder/logger"
import express from "express"
import { promises as fs } from "fs"
import path from "path"
import { WebsocketRequest } from "../../../typings/pluginapi"
import { HttpCode } from "../../common/http"
import { rootPath } from "../constants"
import { replaceTemplates } from "../http"
import { escapeHtml, getMediaMime } from "../util"
const notFoundCodes = ["ENOENT", "EISDIR"]
export const errorHandler: express.ErrorRequestHandler = async (err, req, res, next) => {
if (notFoundCodes.includes(err.code)) {
err.status = HttpCode.NotFound
}
const status = err.status ?? err.statusCode ?? 500
res.status(status)
// Assume anything that explicitly accepts text/html is a user browsing a
// page (as opposed to an xhr request). Don't use `req.accepts()` since
// *every* request that I've seen (in Firefox and Chromium at least)
// includes `*/*` making it always truthy. Even for css/javascript.
if (req.headers.accept && req.headers.accept.includes("text/html")) {
const resourcePath = path.resolve(rootPath, "src/browser/pages/error.html")
res.set("Content-Type", getMediaMime(resourcePath))
const content = await fs.readFile(resourcePath, "utf8")
res.send(
replaceTemplates(req, content)
.replace(/{{ERROR_TITLE}}/g, status)
.replace(/{{ERROR_HEADER}}/g, status)
.replace(/{{ERROR_BODY}}/g, escapeHtml(err.message)),
)
} else {
res.json({
error: err.message,
...(err.details || {}),
})
}
}
export const wsErrorHandler: express.ErrorRequestHandler = async (err, req, res, next) => {
logger.error(`${err.message} ${err.stack}`)
;(req as WebsocketRequest).ws.end()
}