codekingpro/portable-devtools
115k
1'use strict'
2
3const { parseHeaders } = require('../core/util')
4const DecoratorHandler = require('../handler/decorator-handler')
5const { ResponseError } = require('../core/errors')
6
7class Handler extends DecoratorHandler {
8 #handler
9 #statusCode
10 #contentType
11 #decoder
12 #headers
13 #body
14
15 constructor (opts, { handler }) {
16 super(handler)
17 this.#handler = handler
18 }
19
20 onConnect (abort) {
21 this.#statusCode = 0
22 this.#contentType = null
23 this.#decoder = null
24 this.#headers = null
25 this.#body = ''
26
27 return this.#handler.onConnect(abort)
28 }
29
30 onHeaders (statusCode, rawHeaders, resume, statusMessage, headers = parseHeaders(rawHeaders)) {
31 this.#statusCode = statusCode
32 this.#headers = headers
33 this.#contentType = headers['content-type']
34
35 if (this.#statusCode < 400) {
36 return this.#handler.onHeaders(statusCode, rawHeaders, resume, statusMessage, headers)
37 }
38
39 if (this.#contentType === 'application/json' || this.#contentType === 'text/plain') {
40 this.#decoder = new TextDecoder('utf-8')
41 }
42 }
43
44 onData (chunk) {
45 if (this.#statusCode < 400) {
46 return this.#handler.onData(chunk)
47 }
48
49 this.#body += this.#decoder?.decode(chunk, { stream: true }) ?? ''
50 }
51
52 onComplete (rawTrailers) {
53 if (this.#statusCode >= 400) {
54 this.#body += this.#decoder?.decode(undefined, { stream: false }) ?? ''
55
56 if (this.#contentType === 'application/json') {
57 try {
58 this.#body = JSON.parse(this.#body)
59 } catch {
60 // Do nothing...
61 }
62 }
63
64 let err
65 const stackTraceLimit = Error.stackTraceLimit
66 Error.stackTraceLimit = 0
67 try {
68 err = new ResponseError('Response Error', this.#statusCode, this.#headers, this.#body)
69 } finally {
70 Error.stackTraceLimit = stackTraceLimit
71 }
72
73 this.#handler.onError(err)
74 } else {
75 this.#handler.onComplete(rawTrailers)
76 }
77 }
78
79 onError (err) {
80 this.#handler.onError(err)
81 }
82}
83
84module.exports = (dispatch) => (opts, handler) => opts.throwOnError
85 ? dispatch(opts, new Handler(opts, { handler }))
86 : dispatch(opts, handler)
87 