@atproto/xrpc-server 0.6.4 → 0.7.1
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 +34 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- 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 -74
- 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 +5 -6
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +69 -74
- package/dist/util.js.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +1 -7
- package/src/server.ts +78 -99
- package/src/types.ts +209 -41
- package/src/util.ts +80 -62
- 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)
|
|
@@ -280,59 +282,48 @@ export class Server {
|
|
|
280
282
|
}
|
|
281
283
|
|
|
282
284
|
// run the handler
|
|
283
|
-
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)
|
|
284
305
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
}
|
|
306
|
+
res.status(200)
|
|
307
|
+
setHeaders(res, output)
|
|
288
308
|
|
|
289
|
-
if (outputUnvalidated && isHandlerPipeThrough(outputUnvalidated)) {
|
|
290
|
-
// set headers
|
|
291
|
-
if (outputUnvalidated?.headers) {
|
|
292
|
-
Object.entries(outputUnvalidated.headers).forEach(([name, val]) => {
|
|
293
|
-
res.header(name, val)
|
|
294
|
-
})
|
|
295
|
-
}
|
|
296
|
-
res
|
|
297
|
-
.header('Content-Type', outputUnvalidated.encoding)
|
|
298
|
-
.status(200)
|
|
299
|
-
.send(Buffer.from(outputUnvalidated.buffer))
|
|
300
|
-
return
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (!outputUnvalidated || isHandlerSuccess(outputUnvalidated)) {
|
|
304
|
-
// validate response
|
|
305
|
-
const output = validateResOutput(outputUnvalidated)
|
|
306
|
-
// set headers
|
|
307
|
-
if (output?.headers) {
|
|
308
|
-
Object.entries(output.headers).forEach(([name, val]) => {
|
|
309
|
-
res.header(name, val)
|
|
310
|
-
})
|
|
311
|
-
}
|
|
312
|
-
// send response
|
|
313
309
|
if (
|
|
314
|
-
output
|
|
315
|
-
output
|
|
310
|
+
output.encoding === 'application/json' ||
|
|
311
|
+
output.encoding === 'json'
|
|
316
312
|
) {
|
|
317
313
|
const json = lexToJson(output.body)
|
|
318
|
-
res.
|
|
319
|
-
} else if (output
|
|
314
|
+
res.json(json)
|
|
315
|
+
} else if (output.body instanceof Readable) {
|
|
320
316
|
res.header('Content-Type', output.encoding)
|
|
321
|
-
res
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
.status(200)
|
|
329
|
-
.send(
|
|
330
|
-
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
|
|
331
324
|
? Buffer.from(output.body)
|
|
332
325
|
: output.body,
|
|
333
|
-
|
|
334
|
-
} else {
|
|
335
|
-
res.status(200).end()
|
|
326
|
+
)
|
|
336
327
|
}
|
|
337
328
|
}
|
|
338
329
|
} catch (err: unknown) {
|
|
@@ -364,7 +355,7 @@ export class Server {
|
|
|
364
355
|
// authenticate request
|
|
365
356
|
const auth = await config.auth?.({ req })
|
|
366
357
|
if (isHandlerError(auth)) {
|
|
367
|
-
throw XRPCError.
|
|
358
|
+
throw XRPCError.fromHandlerError(auth)
|
|
368
359
|
}
|
|
369
360
|
// validate request
|
|
370
361
|
let params = decodeQueryParams(def, getQueryParams(req.url))
|
|
@@ -481,30 +472,18 @@ export class Server {
|
|
|
481
472
|
}
|
|
482
473
|
}
|
|
483
474
|
|
|
484
|
-
function
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
if (
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
if (!isString(v['encoding']) || !(v['buffer'] instanceof ArrayBuffer)) {
|
|
493
|
-
return false
|
|
494
|
-
}
|
|
495
|
-
if (v['headers'] !== undefined) {
|
|
496
|
-
if (v['headers'] === null || typeof v['headers'] !== 'object') {
|
|
497
|
-
return false
|
|
498
|
-
}
|
|
499
|
-
if (!Object.values(v['headers']).every(isString)) {
|
|
500
|
-
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)
|
|
501
483
|
}
|
|
502
484
|
}
|
|
503
|
-
return true
|
|
504
485
|
}
|
|
505
486
|
|
|
506
|
-
const isString = (val: unknown): val is string => typeof val === 'string'
|
|
507
|
-
|
|
508
487
|
const kRequestLocals = Symbol('requestLocals')
|
|
509
488
|
|
|
510
489
|
function createLocalsMiddleware(nsid: string): RequestHandler {
|
|
@@ -525,7 +504,7 @@ function createAuthMiddleware(verifier: AuthVerifier): RequestHandler {
|
|
|
525
504
|
try {
|
|
526
505
|
const result = await verifier({ req, res })
|
|
527
506
|
if (isHandlerError(result)) {
|
|
528
|
-
throw XRPCError.
|
|
507
|
+
throw XRPCError.fromHandlerError(result)
|
|
529
508
|
}
|
|
530
509
|
const locals: RequestLocals = req[kRequestLocals]
|
|
531
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
|
}
|