Spaces:
Running
Running
File size: 2,579 Bytes
d4b85c0 |
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 |
import { invariant } from 'outvariant'
import { DeferredPromise } from '@open-draft/deferred-promise'
import { InterceptorError } from './InterceptorError'
const kRequestHandled = Symbol('kRequestHandled')
export const kResponsePromise = Symbol('kResponsePromise')
export class RequestController {
/**
* Internal response promise.
* Available only for the library internals to grab the
* response instance provided by the developer.
* @note This promise cannot be rejected. It's either infinitely
* pending or resolved with whichever Response was passed to `respondWith()`.
*/
[kResponsePromise]: DeferredPromise<Response | Error | undefined>;
/**
* Internal flag indicating if this request has been handled.
* @note The response promise becomes "fulfilled" on the next tick.
*/
[kRequestHandled]: boolean
constructor(private request: Request) {
this[kRequestHandled] = false
this[kResponsePromise] = new DeferredPromise()
}
/**
* Respond to this request with the given `Response` instance.
* @example
* controller.respondWith(new Response())
* controller.respondWith(Response.json({ id }))
* controller.respondWith(Response.error())
*/
public respondWith(response: Response): void {
invariant.as(
InterceptorError,
!this[kRequestHandled],
'Failed to respond to the "%s %s" request: the "request" event has already been handled.',
this.request.method,
this.request.url
)
this[kRequestHandled] = true
this[kResponsePromise].resolve(response)
/**
* @note The request conrtoller doesn't do anything
* apart from letting the interceptor await the response
* provided by the developer through the response promise.
* Each interceptor implements the actual respondWith/errorWith
* logic based on that interceptor's needs.
*/
}
/**
* Error this request with the given error.
* @example
* controller.errorWith()
* controller.errorWith(new Error('Oops!'))
*/
public errorWith(error?: Error): void {
invariant.as(
InterceptorError,
!this[kRequestHandled],
'Failed to error the "%s %s" request: the "request" event has already been handled.',
this.request.method,
this.request.url
)
this[kRequestHandled] = true
/**
* @note Resolve the response promise, not reject.
* This helps us differentiate between unhandled exceptions
* and intended errors ("errorWith") while waiting for the response.
*/
this[kResponsePromise].resolve(error)
}
}
|