1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- '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 }))
- }
- }
- }
|