@atproto/xrpc-server 0.6.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +55 -78
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +73 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +97 -40
- package/dist/types.js.map +1 -1
- package/dist/util.d.ts +6 -2
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +85 -27
- package/dist/util.js.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +1 -1
- package/src/server.ts +78 -104
- package/src/types.ts +209 -41
- package/src/util.ts +103 -33
- package/tests/bodies.test.ts +120 -21
- package/tests/parsing.test.ts +89 -0
package/src/server.ts
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import express, {
|
|
3
|
-
Application,
|
|
4
|
-
Express,
|
|
5
|
-
Router,
|
|
6
|
-
Request,
|
|
7
|
-
Response,
|
|
8
|
-
ErrorRequestHandler,
|
|
9
|
-
NextFunction,
|
|
10
|
-
RequestHandler,
|
|
11
|
-
} from 'express'
|
|
1
|
+
import { check, schema } from '@atproto/common'
|
|
12
2
|
import {
|
|
13
3
|
LexiconDoc,
|
|
14
4
|
Lexicons,
|
|
@@ -17,31 +7,45 @@ import {
|
|
|
17
7
|
LexXrpcQuery,
|
|
18
8
|
LexXrpcSubscription,
|
|
19
9
|
} from '@atproto/lexicon'
|
|
20
|
-
import
|
|
10
|
+
import express, {
|
|
11
|
+
Application,
|
|
12
|
+
ErrorRequestHandler,
|
|
13
|
+
Express,
|
|
14
|
+
NextFunction,
|
|
15
|
+
Request,
|
|
16
|
+
RequestHandler,
|
|
17
|
+
Response,
|
|
18
|
+
Router,
|
|
19
|
+
} from 'express'
|
|
20
|
+
import { Readable } from 'node:stream'
|
|
21
|
+
import { pipeline } from 'node:stream/promises'
|
|
22
|
+
|
|
23
|
+
import log from './logger'
|
|
24
|
+
import { consumeMany } from './rate-limiter'
|
|
21
25
|
import { ErrorFrame, Frame, MessageFrame, XrpcStreamServer } from './stream'
|
|
22
26
|
import {
|
|
23
|
-
XRPCHandler,
|
|
24
|
-
XRPCError,
|
|
25
|
-
InvalidRequestError,
|
|
26
|
-
HandlerOutput,
|
|
27
|
-
HandlerSuccess,
|
|
28
|
-
handlerSuccess,
|
|
29
|
-
XRPCHandlerConfig,
|
|
30
|
-
MethodNotImplementedError,
|
|
31
|
-
HandlerAuth,
|
|
32
27
|
AuthVerifier,
|
|
28
|
+
HandlerAuth,
|
|
29
|
+
HandlerPipeThrough,
|
|
30
|
+
HandlerSuccess,
|
|
31
|
+
InternalServerError,
|
|
32
|
+
InvalidRequestError,
|
|
33
33
|
isHandlerError,
|
|
34
|
+
isHandlerPipeThroughBuffer,
|
|
35
|
+
isHandlerPipeThroughStream,
|
|
36
|
+
isShared,
|
|
37
|
+
MethodNotImplementedError,
|
|
34
38
|
Options,
|
|
35
|
-
XRPCStreamHandlerConfig,
|
|
36
|
-
XRPCStreamHandler,
|
|
37
39
|
Params,
|
|
38
|
-
InternalServerError,
|
|
39
|
-
XRPCReqContext,
|
|
40
|
-
RateLimiterI,
|
|
41
40
|
RateLimiterConsume,
|
|
42
|
-
|
|
41
|
+
RateLimiterI,
|
|
43
42
|
RateLimitExceededError,
|
|
44
|
-
|
|
43
|
+
XRPCError,
|
|
44
|
+
XRPCHandler,
|
|
45
|
+
XRPCHandlerConfig,
|
|
46
|
+
XRPCReqContext,
|
|
47
|
+
XRPCStreamHandler,
|
|
48
|
+
XRPCStreamHandlerConfig,
|
|
45
49
|
} from './types'
|
|
46
50
|
import {
|
|
47
51
|
decodeQueryParams,
|
|
@@ -49,8 +53,6 @@ import {
|
|
|
49
53
|
validateInput,
|
|
50
54
|
validateOutput,
|
|
51
55
|
} from './util'
|
|
52
|
-
import log from './logger'
|
|
53
|
-
import { consumeMany } from './rate-limiter'
|
|
54
56
|
|
|
55
57
|
export function createServer(lexicons?: LexiconDoc[], options?: Options) {
|
|
56
58
|
return new Server(lexicons, options)
|
|
@@ -243,8 +245,8 @@ export class Server {
|
|
|
243
245
|
validateInput(nsid, def, req, routeOpts, this.lex)
|
|
244
246
|
const validateResOutput =
|
|
245
247
|
this.options.validateResponse === false
|
|
246
|
-
?
|
|
247
|
-
: (output
|
|
248
|
+
? null
|
|
249
|
+
: (output: undefined | HandlerSuccess) =>
|
|
248
250
|
validateOutput(nsid, def, output, this.lex)
|
|
249
251
|
const assertValidXrpcParams = (params: unknown) =>
|
|
250
252
|
this.lex.assertValidXrpcParams(nsid, params)
|
|
@@ -263,11 +265,6 @@ export class Server {
|
|
|
263
265
|
}
|
|
264
266
|
const input = validateReqInput(req)
|
|
265
267
|
|
|
266
|
-
if (input?.body instanceof Readable) {
|
|
267
|
-
// If the body stream errors at any time, abort the request
|
|
268
|
-
input.body.once('error', next)
|
|
269
|
-
}
|
|
270
|
-
|
|
271
268
|
const locals: RequestLocals = req[kRequestLocals]
|
|
272
269
|
|
|
273
270
|
const reqCtx: XRPCReqContext = {
|
|
@@ -285,59 +282,48 @@ export class Server {
|
|
|
285
282
|
}
|
|
286
283
|
|
|
287
284
|
// run the handler
|
|
288
|
-
const
|
|
285
|
+
const output = await routeCfg.handler(reqCtx)
|
|
286
|
+
|
|
287
|
+
if (!output) {
|
|
288
|
+
validateResOutput?.(output)
|
|
289
|
+
res.status(200)
|
|
290
|
+
res.end()
|
|
291
|
+
} else if (isHandlerPipeThroughStream(output)) {
|
|
292
|
+
setHeaders(res, output)
|
|
293
|
+
res.status(200)
|
|
294
|
+
res.header('Content-Type', output.encoding)
|
|
295
|
+
await pipeline(output.stream, res)
|
|
296
|
+
} else if (isHandlerPipeThroughBuffer(output)) {
|
|
297
|
+
setHeaders(res, output)
|
|
298
|
+
res.status(200)
|
|
299
|
+
res.header('Content-Type', output.encoding)
|
|
300
|
+
res.end(output.buffer)
|
|
301
|
+
} else if (isHandlerError(output)) {
|
|
302
|
+
next(XRPCError.fromError(output))
|
|
303
|
+
} else {
|
|
304
|
+
validateResOutput?.(output)
|
|
289
305
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
306
|
+
res.status(200)
|
|
307
|
+
setHeaders(res, output)
|
|
293
308
|
|
|
294
|
-
if (outputUnvalidated && isHandlerPipeThrough(outputUnvalidated)) {
|
|
295
|
-
// set headers
|
|
296
|
-
if (outputUnvalidated?.headers) {
|
|
297
|
-
Object.entries(outputUnvalidated.headers).forEach(([name, val]) => {
|
|
298
|
-
res.header(name, val)
|
|
299
|
-
})
|
|
300
|
-
}
|
|
301
|
-
res
|
|
302
|
-
.header('Content-Type', outputUnvalidated.encoding)
|
|
303
|
-
.status(200)
|
|
304
|
-
.send(Buffer.from(outputUnvalidated.buffer))
|
|
305
|
-
return
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (!outputUnvalidated || isHandlerSuccess(outputUnvalidated)) {
|
|
309
|
-
// validate response
|
|
310
|
-
const output = validateResOutput(outputUnvalidated)
|
|
311
|
-
// set headers
|
|
312
|
-
if (output?.headers) {
|
|
313
|
-
Object.entries(output.headers).forEach(([name, val]) => {
|
|
314
|
-
res.header(name, val)
|
|
315
|
-
})
|
|
316
|
-
}
|
|
317
|
-
// send response
|
|
318
309
|
if (
|
|
319
|
-
output
|
|
320
|
-
output
|
|
310
|
+
output.encoding === 'application/json' ||
|
|
311
|
+
output.encoding === 'json'
|
|
321
312
|
) {
|
|
322
313
|
const json = lexToJson(output.body)
|
|
323
|
-
res.
|
|
324
|
-
} else if (output
|
|
314
|
+
res.json(json)
|
|
315
|
+
} else if (output.body instanceof Readable) {
|
|
325
316
|
res.header('Content-Type', output.encoding)
|
|
326
|
-
res
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
.status(200)
|
|
334
|
-
.send(
|
|
335
|
-
output.body instanceof Uint8Array
|
|
317
|
+
await pipeline(output.body, res)
|
|
318
|
+
} else {
|
|
319
|
+
res.header('Content-Type', output.encoding)
|
|
320
|
+
res.send(
|
|
321
|
+
Buffer.isBuffer(output.body)
|
|
322
|
+
? output.body
|
|
323
|
+
: output.body instanceof Uint8Array
|
|
336
324
|
? Buffer.from(output.body)
|
|
337
325
|
: output.body,
|
|
338
|
-
|
|
339
|
-
} else {
|
|
340
|
-
res.status(200).end()
|
|
326
|
+
)
|
|
341
327
|
}
|
|
342
328
|
}
|
|
343
329
|
} catch (err: unknown) {
|
|
@@ -369,7 +355,7 @@ export class Server {
|
|
|
369
355
|
// authenticate request
|
|
370
356
|
const auth = await config.auth?.({ req })
|
|
371
357
|
if (isHandlerError(auth)) {
|
|
372
|
-
throw XRPCError.
|
|
358
|
+
throw XRPCError.fromHandlerError(auth)
|
|
373
359
|
}
|
|
374
360
|
// validate request
|
|
375
361
|
let params = decodeQueryParams(def, getQueryParams(req.url))
|
|
@@ -486,30 +472,18 @@ export class Server {
|
|
|
486
472
|
}
|
|
487
473
|
}
|
|
488
474
|
|
|
489
|
-
function
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if (
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
if (!isString(v['encoding']) || !(v['buffer'] instanceof ArrayBuffer)) {
|
|
498
|
-
return false
|
|
499
|
-
}
|
|
500
|
-
if (v['headers'] !== undefined) {
|
|
501
|
-
if (v['headers'] === null || typeof v['headers'] !== 'object') {
|
|
502
|
-
return false
|
|
503
|
-
}
|
|
504
|
-
if (!Object.values(v['headers']).every(isString)) {
|
|
505
|
-
return false
|
|
475
|
+
function setHeaders(
|
|
476
|
+
res: Response,
|
|
477
|
+
result: HandlerSuccess | HandlerPipeThrough,
|
|
478
|
+
) {
|
|
479
|
+
const { headers } = result
|
|
480
|
+
if (headers) {
|
|
481
|
+
for (const [name, val] of Object.entries(headers)) {
|
|
482
|
+
if (val != null) res.header(name, val)
|
|
506
483
|
}
|
|
507
484
|
}
|
|
508
|
-
return true
|
|
509
485
|
}
|
|
510
486
|
|
|
511
|
-
const isString = (val: unknown): val is string => typeof val === 'string'
|
|
512
|
-
|
|
513
487
|
const kRequestLocals = Symbol('requestLocals')
|
|
514
488
|
|
|
515
489
|
function createLocalsMiddleware(nsid: string): RequestHandler {
|
|
@@ -530,7 +504,7 @@ function createAuthMiddleware(verifier: AuthVerifier): RequestHandler {
|
|
|
530
504
|
try {
|
|
531
505
|
const result = await verifier({ req, res })
|
|
532
506
|
if (isHandlerError(result)) {
|
|
533
|
-
throw XRPCError.
|
|
507
|
+
throw XRPCError.fromHandlerError(result)
|
|
534
508
|
}
|
|
535
509
|
const locals: RequestLocals = req[kRequestLocals]
|
|
536
510
|
locals.auth = result
|
package/src/types.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { IncomingMessage } from 'http'
|
|
2
|
-
import express from 'express'
|
|
3
|
-
import { isHttpError } from 'http-errors'
|
|
4
|
-
import zod from 'zod'
|
|
5
1
|
import {
|
|
6
2
|
ResponseType,
|
|
7
|
-
ResponseTypeStrings,
|
|
8
3
|
ResponseTypeNames,
|
|
4
|
+
ResponseTypeStrings,
|
|
5
|
+
XRPCError as XRPCClientError,
|
|
9
6
|
} from '@atproto/xrpc'
|
|
7
|
+
import express from 'express'
|
|
8
|
+
import { IncomingMessage } from 'http'
|
|
9
|
+
import { isHttpError } from 'http-errors'
|
|
10
|
+
import { Readable } from 'stream'
|
|
11
|
+
import zod from 'zod'
|
|
10
12
|
|
|
11
13
|
export type CatchallHandler = (
|
|
12
14
|
req: express.Request,
|
|
@@ -46,18 +48,40 @@ export const handlerAuth = zod.object({
|
|
|
46
48
|
})
|
|
47
49
|
export type HandlerAuth = zod.infer<typeof handlerAuth>
|
|
48
50
|
|
|
51
|
+
export const headersSchema = zod.record(zod.string())
|
|
52
|
+
|
|
49
53
|
export const handlerSuccess = zod.object({
|
|
50
54
|
encoding: zod.string(),
|
|
51
55
|
body: zod.any(),
|
|
52
|
-
headers:
|
|
56
|
+
headers: headersSchema.optional(),
|
|
53
57
|
})
|
|
54
58
|
export type HandlerSuccess = zod.infer<typeof handlerSuccess>
|
|
55
59
|
|
|
56
|
-
export const
|
|
60
|
+
export const handlerPipeThroughBuffer = zod.object({
|
|
57
61
|
encoding: zod.string(),
|
|
58
|
-
buffer: zod.instanceof(
|
|
59
|
-
headers:
|
|
62
|
+
buffer: zod.instanceof(Buffer),
|
|
63
|
+
headers: headersSchema.optional(),
|
|
60
64
|
})
|
|
65
|
+
|
|
66
|
+
export type HandlerPipeThroughBuffer = zod.infer<
|
|
67
|
+
typeof handlerPipeThroughBuffer
|
|
68
|
+
>
|
|
69
|
+
|
|
70
|
+
export const handlerPipeThroughStream = zod.object({
|
|
71
|
+
encoding: zod.string(),
|
|
72
|
+
stream: zod.instanceof(Readable),
|
|
73
|
+
headers: headersSchema.optional(),
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
export type HandlerPipeThroughStream = zod.infer<
|
|
77
|
+
typeof handlerPipeThroughStream
|
|
78
|
+
>
|
|
79
|
+
|
|
80
|
+
export const handlerPipeThrough = zod.union([
|
|
81
|
+
handlerPipeThroughBuffer,
|
|
82
|
+
handlerPipeThroughStream,
|
|
83
|
+
])
|
|
84
|
+
|
|
61
85
|
export type HandlerPipeThrough = zod.infer<typeof handlerPipeThrough>
|
|
62
86
|
|
|
63
87
|
export const handlerError = zod.object({
|
|
@@ -186,8 +210,9 @@ export class XRPCError extends Error {
|
|
|
186
210
|
public type: ResponseType,
|
|
187
211
|
public errorMessage?: string,
|
|
188
212
|
public customErrorName?: string,
|
|
213
|
+
options?: ErrorOptions,
|
|
189
214
|
) {
|
|
190
|
-
super(errorMessage)
|
|
215
|
+
super(errorMessage, options)
|
|
191
216
|
}
|
|
192
217
|
|
|
193
218
|
get payload() {
|
|
@@ -208,22 +233,36 @@ export class XRPCError extends Error {
|
|
|
208
233
|
return ResponseTypeStrings[this.type]
|
|
209
234
|
}
|
|
210
235
|
|
|
211
|
-
static fromError(
|
|
212
|
-
if (
|
|
213
|
-
return
|
|
236
|
+
static fromError(cause: unknown): XRPCError {
|
|
237
|
+
if (cause instanceof XRPCError) {
|
|
238
|
+
return cause
|
|
214
239
|
}
|
|
215
|
-
|
|
216
|
-
if (
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
} else {
|
|
223
|
-
resultErr = new InternalServerError('Unexpected internal server error')
|
|
240
|
+
|
|
241
|
+
if (cause instanceof XRPCClientError) {
|
|
242
|
+
return new XRPCError(cause.status, cause.message, cause.error, { cause })
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (isHttpError(cause)) {
|
|
246
|
+
return new XRPCError(cause.status, cause.message, cause.name, { cause })
|
|
224
247
|
}
|
|
225
|
-
|
|
226
|
-
|
|
248
|
+
|
|
249
|
+
if (isHandlerError(cause)) {
|
|
250
|
+
return this.fromHandlerError(cause)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (cause instanceof Error) {
|
|
254
|
+
return new InternalServerError(cause.message, undefined, { cause })
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return new InternalServerError(
|
|
258
|
+
'Unexpected internal server error',
|
|
259
|
+
undefined,
|
|
260
|
+
{ cause },
|
|
261
|
+
)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
static fromHandlerError(err: HandlerError): XRPCError {
|
|
265
|
+
return new XRPCError(err.status, err.message, err.error, { cause: err })
|
|
227
266
|
}
|
|
228
267
|
}
|
|
229
268
|
|
|
@@ -237,21 +276,67 @@ export function isHandlerError(v: unknown): v is HandlerError {
|
|
|
237
276
|
)
|
|
238
277
|
}
|
|
239
278
|
|
|
279
|
+
export function isHandlerPipeThroughBuffer(
|
|
280
|
+
v: HandlerOutput,
|
|
281
|
+
): v is HandlerPipeThroughBuffer {
|
|
282
|
+
// We only need to discriminate between possible HandlerOutput values
|
|
283
|
+
return v['buffer'] !== undefined
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export function isHandlerPipeThroughStream(
|
|
287
|
+
v: HandlerOutput,
|
|
288
|
+
): v is HandlerPipeThroughStream {
|
|
289
|
+
// We only need to discriminate between possible HandlerOutput values
|
|
290
|
+
return v['stream'] !== undefined
|
|
291
|
+
}
|
|
292
|
+
|
|
240
293
|
export class InvalidRequestError extends XRPCError {
|
|
241
|
-
constructor(
|
|
242
|
-
|
|
294
|
+
constructor(
|
|
295
|
+
errorMessage?: string,
|
|
296
|
+
customErrorName?: string,
|
|
297
|
+
options?: ErrorOptions,
|
|
298
|
+
) {
|
|
299
|
+
super(ResponseType.InvalidRequest, errorMessage, customErrorName, options)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
[Symbol.hasInstance](instance: unknown): boolean {
|
|
303
|
+
return (
|
|
304
|
+
instance instanceof XRPCError &&
|
|
305
|
+
instance.type === ResponseType.InvalidRequest
|
|
306
|
+
)
|
|
243
307
|
}
|
|
244
308
|
}
|
|
245
309
|
|
|
246
310
|
export class AuthRequiredError extends XRPCError {
|
|
247
|
-
constructor(
|
|
248
|
-
|
|
311
|
+
constructor(
|
|
312
|
+
errorMessage?: string,
|
|
313
|
+
customErrorName?: string,
|
|
314
|
+
options?: ErrorOptions,
|
|
315
|
+
) {
|
|
316
|
+
super(ResponseType.AuthRequired, errorMessage, customErrorName, options)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
[Symbol.hasInstance](instance: unknown): boolean {
|
|
320
|
+
return (
|
|
321
|
+
instance instanceof XRPCError &&
|
|
322
|
+
instance.type === ResponseType.AuthRequired
|
|
323
|
+
)
|
|
249
324
|
}
|
|
250
325
|
}
|
|
251
326
|
|
|
252
327
|
export class ForbiddenError extends XRPCError {
|
|
253
|
-
constructor(
|
|
254
|
-
|
|
328
|
+
constructor(
|
|
329
|
+
errorMessage?: string,
|
|
330
|
+
customErrorName?: string,
|
|
331
|
+
options?: ErrorOptions,
|
|
332
|
+
) {
|
|
333
|
+
super(ResponseType.Forbidden, errorMessage, customErrorName, options)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
[Symbol.hasInstance](instance: unknown): boolean {
|
|
337
|
+
return (
|
|
338
|
+
instance instanceof XRPCError && instance.type === ResponseType.Forbidden
|
|
339
|
+
)
|
|
255
340
|
}
|
|
256
341
|
}
|
|
257
342
|
|
|
@@ -260,37 +345,120 @@ export class RateLimitExceededError extends XRPCError {
|
|
|
260
345
|
public status: RateLimiterStatus,
|
|
261
346
|
errorMessage?: string,
|
|
262
347
|
customErrorName?: string,
|
|
348
|
+
options?: ErrorOptions,
|
|
263
349
|
) {
|
|
264
|
-
super(
|
|
350
|
+
super(
|
|
351
|
+
ResponseType.RateLimitExceeded,
|
|
352
|
+
errorMessage,
|
|
353
|
+
customErrorName,
|
|
354
|
+
options,
|
|
355
|
+
)
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
[Symbol.hasInstance](instance: unknown): boolean {
|
|
359
|
+
return (
|
|
360
|
+
instance instanceof XRPCError &&
|
|
361
|
+
instance.type === ResponseType.RateLimitExceeded
|
|
362
|
+
)
|
|
265
363
|
}
|
|
266
364
|
}
|
|
267
365
|
|
|
268
366
|
export class InternalServerError extends XRPCError {
|
|
269
|
-
constructor(
|
|
270
|
-
|
|
367
|
+
constructor(
|
|
368
|
+
errorMessage?: string,
|
|
369
|
+
customErrorName?: string,
|
|
370
|
+
options?: ErrorOptions,
|
|
371
|
+
) {
|
|
372
|
+
super(
|
|
373
|
+
ResponseType.InternalServerError,
|
|
374
|
+
errorMessage,
|
|
375
|
+
customErrorName,
|
|
376
|
+
options,
|
|
377
|
+
)
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
[Symbol.hasInstance](instance: unknown): boolean {
|
|
381
|
+
return (
|
|
382
|
+
instance instanceof XRPCError &&
|
|
383
|
+
instance.type === ResponseType.InternalServerError
|
|
384
|
+
)
|
|
271
385
|
}
|
|
272
386
|
}
|
|
273
387
|
|
|
274
388
|
export class UpstreamFailureError extends XRPCError {
|
|
275
|
-
constructor(
|
|
276
|
-
|
|
389
|
+
constructor(
|
|
390
|
+
errorMessage?: string,
|
|
391
|
+
customErrorName?: string,
|
|
392
|
+
options?: ErrorOptions,
|
|
393
|
+
) {
|
|
394
|
+
super(ResponseType.UpstreamFailure, errorMessage, customErrorName, options)
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
[Symbol.hasInstance](instance: unknown): boolean {
|
|
398
|
+
return (
|
|
399
|
+
instance instanceof XRPCError &&
|
|
400
|
+
instance.type === ResponseType.UpstreamFailure
|
|
401
|
+
)
|
|
277
402
|
}
|
|
278
403
|
}
|
|
279
404
|
|
|
280
405
|
export class NotEnoughResourcesError extends XRPCError {
|
|
281
|
-
constructor(
|
|
282
|
-
|
|
406
|
+
constructor(
|
|
407
|
+
errorMessage?: string,
|
|
408
|
+
customErrorName?: string,
|
|
409
|
+
options?: ErrorOptions,
|
|
410
|
+
) {
|
|
411
|
+
super(
|
|
412
|
+
ResponseType.NotEnoughResources,
|
|
413
|
+
errorMessage,
|
|
414
|
+
customErrorName,
|
|
415
|
+
options,
|
|
416
|
+
)
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
[Symbol.hasInstance](instance: unknown): boolean {
|
|
420
|
+
return (
|
|
421
|
+
instance instanceof XRPCError &&
|
|
422
|
+
instance.type === ResponseType.NotEnoughResources
|
|
423
|
+
)
|
|
283
424
|
}
|
|
284
425
|
}
|
|
285
426
|
|
|
286
427
|
export class UpstreamTimeoutError extends XRPCError {
|
|
287
|
-
constructor(
|
|
288
|
-
|
|
428
|
+
constructor(
|
|
429
|
+
errorMessage?: string,
|
|
430
|
+
customErrorName?: string,
|
|
431
|
+
options?: ErrorOptions,
|
|
432
|
+
) {
|
|
433
|
+
super(ResponseType.UpstreamTimeout, errorMessage, customErrorName, options)
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
[Symbol.hasInstance](instance: unknown): boolean {
|
|
437
|
+
return (
|
|
438
|
+
instance instanceof XRPCError &&
|
|
439
|
+
instance.type === ResponseType.UpstreamTimeout
|
|
440
|
+
)
|
|
289
441
|
}
|
|
290
442
|
}
|
|
291
443
|
|
|
292
444
|
export class MethodNotImplementedError extends XRPCError {
|
|
293
|
-
constructor(
|
|
294
|
-
|
|
445
|
+
constructor(
|
|
446
|
+
errorMessage?: string,
|
|
447
|
+
customErrorName?: string,
|
|
448
|
+
options?: ErrorOptions,
|
|
449
|
+
) {
|
|
450
|
+
super(
|
|
451
|
+
ResponseType.MethodNotImplemented,
|
|
452
|
+
errorMessage,
|
|
453
|
+
customErrorName,
|
|
454
|
+
options,
|
|
455
|
+
)
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
[Symbol.hasInstance](instance: unknown): boolean {
|
|
459
|
+
return (
|
|
460
|
+
instance instanceof XRPCError &&
|
|
461
|
+
instance.type === ResponseType.MethodNotImplemented
|
|
462
|
+
)
|
|
295
463
|
}
|
|
296
464
|
}
|