aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/node_modules/undici/lib/interceptor/response-error.js
diff options
context:
space:
mode:
Diffstat (limited to 'vanilla/node_modules/undici/lib/interceptor/response-error.js')
-rw-r--r--vanilla/node_modules/undici/lib/interceptor/response-error.js95
1 files changed, 95 insertions, 0 deletions
diff --git a/vanilla/node_modules/undici/lib/interceptor/response-error.js b/vanilla/node_modules/undici/lib/interceptor/response-error.js
new file mode 100644
index 0000000..a8105aa
--- /dev/null
+++ b/vanilla/node_modules/undici/lib/interceptor/response-error.js
@@ -0,0 +1,95 @@
+'use strict'
+
+// const { parseHeaders } = require('../core/util')
+const DecoratorHandler = require('../handler/decorator-handler')
+const { ResponseError } = require('../core/errors')
+
+class ResponseErrorHandler extends DecoratorHandler {
+ #statusCode
+ #contentType
+ #decoder
+ #headers
+ #body
+
+ constructor (_opts, { handler }) {
+ super(handler)
+ }
+
+ #checkContentType (contentType) {
+ return (this.#contentType ?? '').indexOf(contentType) === 0
+ }
+
+ onRequestStart (controller, context) {
+ this.#statusCode = 0
+ this.#contentType = null
+ this.#decoder = null
+ this.#headers = null
+ this.#body = ''
+
+ return super.onRequestStart(controller, context)
+ }
+
+ onResponseStart (controller, statusCode, headers, statusMessage) {
+ this.#statusCode = statusCode
+ this.#headers = headers
+ this.#contentType = headers['content-type']
+
+ if (this.#statusCode < 400) {
+ return super.onResponseStart(controller, statusCode, headers, statusMessage)
+ }
+
+ if (this.#checkContentType('application/json') || this.#checkContentType('text/plain')) {
+ this.#decoder = new TextDecoder('utf-8')
+ }
+ }
+
+ onResponseData (controller, chunk) {
+ if (this.#statusCode < 400) {
+ return super.onResponseData(controller, chunk)
+ }
+
+ this.#body += this.#decoder?.decode(chunk, { stream: true }) ?? ''
+ }
+
+ onResponseEnd (controller, trailers) {
+ if (this.#statusCode >= 400) {
+ this.#body += this.#decoder?.decode(undefined, { stream: false }) ?? ''
+
+ if (this.#checkContentType('application/json')) {
+ try {
+ this.#body = JSON.parse(this.#body)
+ } catch {
+ // Do nothing...
+ }
+ }
+
+ let err
+ const stackTraceLimit = Error.stackTraceLimit
+ Error.stackTraceLimit = 0
+ try {
+ err = new ResponseError('Response Error', this.#statusCode, {
+ body: this.#body,
+ headers: this.#headers
+ })
+ } finally {
+ Error.stackTraceLimit = stackTraceLimit
+ }
+
+ super.onResponseError(controller, err)
+ } else {
+ super.onResponseEnd(controller, trailers)
+ }
+ }
+
+ onResponseError (controller, err) {
+ super.onResponseError(controller, err)
+ }
+}
+
+module.exports = () => {
+ return (dispatch) => {
+ return function Intercept (opts, handler) {
+ return dispatch(opts, new ResponseErrorHandler(opts, { handler }))
+ }
+ }
+}