@@ -13,19 +13,31 @@ const {
1313 ObjectGetOwnPropertyNames,
1414 ObjectGetPrototypeOf,
1515 ObjectKeys,
16+ ObjectPrototypeHasOwnProperty,
1617 ObjectPrototypeToString,
1718 RangeError,
1819 ReferenceError,
1920 SafeSet,
21+ StringFromCharCode,
22+ StringPrototypeSubstring,
2023 SymbolToStringTag,
2124 SyntaxError,
25+ SymbolFor,
2226 TypeError,
27+ TypedArrayPrototypeGetBuffer,
28+ TypedArrayPrototypeGetByteOffset,
29+ TypedArrayPrototypeGetByteLength,
2330 URIError,
2431} = primordials ;
32+ const { inspect : { custom : customInspectSymbol } } = require ( 'util' ) ;
2533
2634const kSerializedError = 0 ;
2735const kSerializedObject = 1 ;
2836const kInspectedError = 2 ;
37+ const kInspectedSymbol = 3 ;
38+ const kCustomInspectedObject = 4 ;
39+
40+ const kSymbolStringLength = 'Symbol(' . length ;
2941
3042const errors = {
3143 Error, TypeError, RangeError, URIError, SyntaxError, ReferenceError, EvalError,
@@ -42,19 +54,24 @@ function TryGetAllProperties(object, target = object) {
4254 ArrayPrototypeForEach ( keys , ( key ) => {
4355 let descriptor ;
4456 try {
57+ // TODO: create a null-prototype descriptor with needed properties only
4558 descriptor = ObjectGetOwnPropertyDescriptor ( object , key ) ;
4659 } catch { return ; }
4760 const getter = descriptor . get ;
4861 if ( getter && key !== '__proto__' ) {
4962 try {
5063 descriptor . value = FunctionPrototypeCall ( getter , target ) ;
64+ delete descriptor . get ;
65+ delete descriptor . set ;
5166 } catch {
5267 // Continue regardless of error.
5368 }
5469 }
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' ) {
5875 all [ key ] = descriptor ;
5976 }
6077 } ) ;
@@ -95,6 +112,9 @@ function inspect(...args) {
95112let serialize ;
96113function serializeError ( error ) {
97114 if ( ! serialize ) serialize = require ( 'v8' ) . serialize ;
115+ if ( typeof error === 'symbol' ) {
116+ return Buffer . from ( StringFromCharCode ( kInspectedSymbol ) + inspect ( error ) , 'utf8' ) ;
117+ }
98118 try {
99119 if ( typeof error === 'object' &&
100120 ObjectPrototypeToString ( error ) === '[object Error]' ) {
@@ -113,14 +133,27 @@ function serializeError(error) {
113133 } catch {
114134 // Continue regardless of error.
115135 }
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+ }
116144 try {
117145 const serialized = serialize ( error ) ;
118146 return Buffer . concat ( [ Buffer . from ( [ kSerializedObject ] ) , serialized ] ) ;
119147 } catch {
120148 // Continue regardless of error.
121149 }
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 ) ;
124157}
125158
126159let deserialize ;
@@ -132,19 +165,27 @@ function deserializeError(error) {
132165 const ctor = errors [ constructor ] ;
133166 ObjectDefineProperty ( properties , SymbolToStringTag , {
134167 __proto__ : null ,
135- value : { value : 'Error' , configurable : true } ,
168+ value : { __proto__ : null , value : 'Error' , configurable : true } ,
136169 enumerable : true ,
137170 } ) ;
171+ if ( 'cause' in properties && 'value' in properties . cause ) {
172+ properties . cause . value = deserializeError ( properties . cause . value ) ;
173+ }
138174 return ObjectCreate ( ctor . prototype , properties ) ;
139175 }
140176 case kSerializedObject :
141177 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 ) ) ;
147183 }
184+ case kCustomInspectedObject :
185+ return {
186+ __proto__ : null ,
187+ [ customInspectSymbol ] : ( ) => fromBuffer ( error ) . toString ( 'utf8' ) ,
188+ } ;
148189 }
149190 require ( 'assert' ) . fail ( 'This should not happen' ) ;
150191}
0 commit comments