-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathmain.d.ts
More file actions
199 lines (189 loc) · 5.47 KB
/
main.d.ts
File metadata and controls
199 lines (189 loc) · 5.47 KB
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
import {
ErrorName,
ErrorConstructor as RawErrorConstructor,
ErrorInstance as RawErrorInstance,
ErrorParams,
Options as CreateErrorTypesOptions,
} from 'create-error-types'
import { serialize, parse, ErrorObject } from 'error-serializer'
/**
* `modern-errors` options
*/
export interface Options<
ErrorNames extends ErrorName = ErrorName,
ErrorParamsArg extends ErrorParams = ErrorParams,
> {
/**
* URL where users should report internal errors/bugs.
*
* @example 'https://github.com/my-name/my-project/issues'
*/
readonly bugsUrl?: CreateErrorTypesOptions['bugsUrl']
/**
* Called on any `new ErrorType('message', parameters)`.
* Can be used to customize error parameters or to set error type properties.
* By default, any `parameters` are set as error properties.
*
* @example
* ```js
* modernErrors({
* onCreate(error, parameters) {
* const { filePath } = parameters
*
* if (typeof filePath !== 'string') {
* throw new Error('filePath must be a string.')
* }
*
* const hasFilePath = filePath !== undefined
* Object.assign(error, { filePath, hasFilePath })
* },
* })
* ```
*/
readonly onCreate?: (
error: ErrorInstance<ErrorNames>,
params: Parameters<
NonNullable<
CreateErrorTypesOptions<ErrorNames, ErrorParamsArg>['onCreate']
>
>[1],
) => ReturnType<
NonNullable<CreateErrorTypesOptions<ErrorNames, ErrorParamsArg>['onCreate']>
>
}
/**
* Any error name passed as argument is returned as an error type.
*
* @example
* ```js
* export const { InputError, AuthError, DatabaseError, errorHandler, parse } =
* modernErrors(['InputError', 'AuthError', 'DatabaseError'])
* ```
*/
export type Result<
ErrorNames extends ErrorName = ErrorName,
ErrorParamsArg extends ErrorParams = ErrorParams,
> = {
[errorName in ErrorNames]: ErrorConstructor<errorName, ErrorParamsArg>
} & {
/**
* Error handler that should wrap each main function.
*
* @example
* ```js
* export const main = async function (filePath) {
* try {
* return await readContents(filePath)
* } catch (error) {
* // `errorHandler()` returns `error`, so `throw` must be used
* throw errorHandler(error)
* }
* }
* ```
*/
errorHandler: ErrorHandler<ErrorNames>
/**
* Convert an error plain object into an Error instance.
*
* @example
* ```js
* try {
* await readFile(filePath)
* } catch (cause) {
* const error = new InputError('Could not read the file.', {
* cause,
* filePath: '/path',
* })
* const errorObject = error.toJSON()
* // {
* // name: 'InputError',
* // message: 'Could not read the file',
* // stack: '...',
* // cause: { name: 'Error', ... },
* // filePath: '/path'
* // }
* const errorString = JSON.stringify(error)
* // '{"name":"InputError",...}'
* const newErrorObject = JSON.parse(errorString)
* const newError = parse(newErrorObject)
* // InputError: Could not read the file.
* // filePath: '/path'
* // [cause]: Error: ...
* }
* ```
*/
parse: Parse
}
export type ErrorConstructor<
ErrorNames extends ErrorName = ErrorName,
ErrorParamsArg extends ErrorParams = ErrorParams,
> = new (
...args: ConstructorParameters<
RawErrorConstructor<ErrorNames, ErrorParamsArg>
>
) => ErrorInstance<ErrorNames>
export type ErrorInstance<ErrorNames extends ErrorName = ErrorName> =
RawErrorInstance<ErrorNames> & {
/**
* Convert errors to plain objects that are
* [always safe](https://github.com/ehmicky/error-serializer#json-safety) to
* serialize with JSON
* ([or YAML](https://github.com/ehmicky/error-serializer#custom-serializationparsing),
* etc.). All error properties
* [are kept](https://github.com/ehmicky/error-serializer#additional-error-properties),
* including
* [`cause`](https://github.com/ehmicky/error-serializer#errorcause-and-aggregateerror).
*
* @example
* ```js
* try {
* await readFile(filePath)
* } catch (cause) {
* const error = new InputError('Could not read the file.', {
* cause,
* filePath: '/path',
* })
* const errorObject = error.toJSON()
* // {
* // name: 'InputError',
* // message: 'Could not read the file',
* // stack: '...',
* // cause: { name: 'Error', ... },
* // filePath: '/path'
* // }
* const errorString = JSON.stringify(error)
* // '{"name":"InputError",...}'
* }
* ```
*/
toJSON: () => ReturnType<typeof serialize<RawErrorInstance<ErrorNames>>>
}
/**
* Type of `errorHandler()`
*/
export type ErrorHandler<ErrorNames extends ErrorName = ErrorName> = (
error: unknown,
) => ErrorInstance<ErrorNames>
/**
* Type of `parse()`
*/
export type Parse = <ArgType>(
value: ArgType,
) => ReturnType<typeof parse<ArgType, { loose: true }>>
export type { ErrorName, ErrorObject, ErrorParams }
/**
* Creates custom error types.
*
* @example
* ```js
* export const { InputError, AuthError, DatabaseError, errorHandler, parse } =
* modernErrors(['InputError', 'AuthError', 'DatabaseError'])
* ```
*/
export default function modernErrors<
ErrorParamsArg extends ErrorParams = ErrorParams,
ErrorNames extends ErrorName[] = [],
>(
errorNames: ErrorNames,
options?: Options<ErrorNames[number], ErrorParamsArg>,
): Result<ErrorNames[number], ErrorParamsArg>