@@ -13,19 +13,31 @@ const {
13
13
ObjectGetOwnPropertyNames,
14
14
ObjectGetPrototypeOf,
15
15
ObjectKeys,
16
+ ObjectPrototypeHasOwnProperty,
16
17
ObjectPrototypeToString,
17
18
RangeError,
18
19
ReferenceError,
19
20
SafeSet,
21
+ StringFromCharCode,
22
+ StringPrototypeSubstring,
20
23
SymbolToStringTag,
21
24
SyntaxError,
25
+ SymbolFor,
22
26
TypeError,
27
+ TypedArrayPrototypeGetBuffer,
28
+ TypedArrayPrototypeGetByteOffset,
29
+ TypedArrayPrototypeGetByteLength,
23
30
URIError,
24
31
} = primordials ;
32
+ const { inspect : { custom : customInspectSymbol } } = require ( 'util' ) ;
25
33
26
34
const kSerializedError = 0 ;
27
35
const kSerializedObject = 1 ;
28
36
const kInspectedError = 2 ;
37
+ const kInspectedSymbol = 3 ;
38
+ const kCustomInspectedObject = 4 ;
39
+
40
+ const kSymbolStringLength = 'Symbol(' . length ;
29
41
30
42
const errors = {
31
43
Error, TypeError, RangeError, URIError, SyntaxError, ReferenceError, EvalError,
@@ -42,19 +54,24 @@ function TryGetAllProperties(object, target = object) {
42
54
ArrayPrototypeForEach ( keys , ( key ) => {
43
55
let descriptor ;
44
56
try {
57
+ // TODO: create a null-prototype descriptor with needed properties only
45
58
descriptor = ObjectGetOwnPropertyDescriptor ( object , key ) ;
46
59
} catch { return ; }
47
60
const getter = descriptor . get ;
48
61
if ( getter && key !== '__proto__' ) {
49
62
try {
50
63
descriptor . value = FunctionPrototypeCall ( getter , target ) ;
64
+ delete descriptor . get ;
65
+ delete descriptor . set ;
51
66
} catch {
52
67
// Continue regardless of error.
53
68
}
54
69
}
55
- if ( 'value' in descriptor && typeof descriptor . value !== 'function' ) {
56
- delete descriptor . get ;
57
- delete descriptor . set ;
70
+ if ( key === 'cause' ) {
71
+ descriptor . value = serializeError ( descriptor . value ) ;
72
+ all [ key ] = descriptor ;
73
+ } else if ( 'value' in descriptor &&
74
+ typeof descriptor . value !== 'function' && typeof descriptor . value !== 'symbol' ) {
58
75
all [ key ] = descriptor ;
59
76
}
60
77
} ) ;
@@ -95,6 +112,9 @@ function inspect(...args) {
95
112
let serialize ;
96
113
function serializeError ( error ) {
97
114
if ( ! serialize ) serialize = require ( 'v8' ) . serialize ;
115
+ if ( typeof error === 'symbol' ) {
116
+ return Buffer . from ( StringFromCharCode ( kInspectedSymbol ) + inspect ( error ) , 'utf8' ) ;
117
+ }
98
118
try {
99
119
if ( typeof error === 'object' &&
100
120
ObjectPrototypeToString ( error ) === '[object Error]' ) {
@@ -113,14 +133,27 @@ function serializeError(error) {
113
133
} catch {
114
134
// Continue regardless of error.
115
135
}
136
+ try {
137
+ if ( error != null &&
138
+ ObjectPrototypeHasOwnProperty ( error , customInspectSymbol ) ) {
139
+ return Buffer . from ( StringFromCharCode ( kCustomInspectedObject ) + inspect ( error ) , 'utf8' ) ;
140
+ }
141
+ } catch {
142
+ // Continue regardless of error.
143
+ }
116
144
try {
117
145
const serialized = serialize ( error ) ;
118
146
return Buffer . concat ( [ Buffer . from ( [ kSerializedObject ] ) , serialized ] ) ;
119
147
} catch {
120
148
// Continue regardless of error.
121
149
}
122
- return Buffer . concat ( [ Buffer . from ( [ kInspectedError ] ) ,
123
- Buffer . from ( inspect ( error ) , 'utf8' ) ] ) ;
150
+ return Buffer . from ( StringFromCharCode ( kInspectedError ) + inspect ( error ) , 'utf8' ) ;
151
+ }
152
+
153
+ function fromBuffer ( error ) {
154
+ return Buffer . from ( TypedArrayPrototypeGetBuffer ( error ) ,
155
+ TypedArrayPrototypeGetByteOffset ( error ) + 1 ,
156
+ TypedArrayPrototypeGetByteLength ( error ) - 1 ) ;
124
157
}
125
158
126
159
let deserialize ;
@@ -132,19 +165,27 @@ function deserializeError(error) {
132
165
const ctor = errors [ constructor ] ;
133
166
ObjectDefineProperty ( properties , SymbolToStringTag , {
134
167
__proto__ : null ,
135
- value : { value : 'Error' , configurable : true } ,
168
+ value : { __proto__ : null , value : 'Error' , configurable : true } ,
136
169
enumerable : true ,
137
170
} ) ;
171
+ if ( 'cause' in properties && 'value' in properties . cause ) {
172
+ properties . cause . value = deserializeError ( properties . cause . value ) ;
173
+ }
138
174
return ObjectCreate ( ctor . prototype , properties ) ;
139
175
}
140
176
case kSerializedObject :
141
177
return deserialize ( error . subarray ( 1 ) ) ;
142
- case kInspectedError : {
143
- const buf = Buffer . from ( error . buffer ,
144
- error . byteOffset + 1 ,
145
- error . byteLength - 1 ) ;
146
- return buf . toString ( 'utf8' ) ;
178
+ case kInspectedError :
179
+ return fromBuffer ( error ) . toString ( 'utf8' ) ;
180
+ case kInspectedSymbol : {
181
+ const buf = fromBuffer ( error ) ;
182
+ return SymbolFor ( StringPrototypeSubstring ( buf . toString ( 'utf8' ) , kSymbolStringLength , buf . length - 1 ) ) ;
147
183
}
184
+ case kCustomInspectedObject :
185
+ return {
186
+ __proto__ : null ,
187
+ [ customInspectSymbol ] : ( ) => fromBuffer ( error ) . toString ( 'utf8' ) ,
188
+ } ;
148
189
}
149
190
require ( 'assert' ) . fail ( 'This should not happen' ) ;
150
191
}
0 commit comments