-
Notifications
You must be signed in to change notification settings - Fork 2
/
mod.ts
123 lines (108 loc) · 2.68 KB
/
mod.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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*!
* Copyright (c) 2020 Henry Zhuang
* MIT Licensed
*/
import { Status, STATUS_TEXT } from "./deps.ts";
export abstract class HttpError extends Error {
name: string;
message: string;
status: number;
statusCode: number;
expose: boolean = false;
[key: string]: any
constructor(code: number, message?: string) {
super(message);
if (!Status[code]) {
throw TypeError(`Unknown HTTP Status Code \`${code}\``);
}
if (code < 400 || code >= 600) {
throw TypeError(
`Only 4xx or 5xx status codes allowed, but got \`${code}\``,
);
}
if (code >= 400 && code < 500) {
this.expose = true;
}
let className = Status[code];
if (!className.endsWith("Error")) {
className += "Error";
}
const msg = message != null ? message : STATUS_TEXT.get(code)!;
this.message = msg;
this.status = this.statusCode = code;
this.name = className;
(Error as any).captureStackTrace(this, this.constructor);
Object.setPrototypeOf(this, new.target.prototype);
}
toString() {
return `${this.name} [${this.status}]: ${this.message}`;
}
toJSON() {
return {
name: this.name,
status: this.status,
message: this.message,
};
}
}
class HttpErrorImpl extends HttpError {}
export interface Props {
[key: string]: any;
}
export interface IError extends Error {
status: number;
statusCode: number;
expose: boolean;
[key: string]: any;
}
/**
* Create a new HttpError.
*
* @returns {HttpError}
* @public
*/
export function createError(
status: number,
message?: string,
props?: Props,
): HttpError;
export function createError(status: number, props: Props): HttpError;
export function createError(err: Error, props?: Props): IError;
export function createError(
status: any,
message?: any,
props?: Props,
): HttpError | Error {
let err;
if (status instanceof Error) {
err = status as IError;
status = err.status || err.statusCode;
if (
typeof status !== "number" ||
(!Status[status] && (status < 400 || status >= 600))
) {
status = 500;
}
props = message;
} else if (typeof message === "string") {
err = new HttpErrorImpl(status, message);
(Error as any).captureStackTrace(err, createError);
} else {
props = message;
err = new HttpErrorImpl(status);
(Error as any).captureStackTrace(err, createError);
}
if (!(err instanceof HttpError) || err.status !== status) {
// add properties to generic error
err.expose = status < 500;
err.status = err.statusCode = status;
}
if (props) {
for (let key in props) {
if (key !== "status") {
err[key] = props[key];
}
}
}
return err;
}