@@ -36,6 +36,7 @@ const kSerializedObject = 1;
3636const kInspectedError = 2 ;
3737const kInspectedSymbol = 3 ;
3838const kCustomInspectedObject = 4 ;
39+ const kCircularReference = 5 ;
3940
4041const kSymbolStringLength = 'Symbol(' . length ;
4142
@@ -44,12 +45,12 @@ const errors = {
4445} ;
4546const errorConstructorNames = new SafeSet ( ObjectKeys ( errors ) ) ;
4647
47- function TryGetAllProperties ( object , target = object ) {
48+ function TryGetAllProperties ( object , target = object , rememberSet ) {
4849 const all = { __proto__ : null } ;
4950 if ( object === null )
5051 return all ;
5152 ObjectAssign ( all ,
52- TryGetAllProperties ( ObjectGetPrototypeOf ( object ) , target ) ) ;
53+ TryGetAllProperties ( ObjectGetPrototypeOf ( object ) , target , rememberSet ) ) ;
5354 const keys = ObjectGetOwnPropertyNames ( object ) ;
5455 ArrayPrototypeForEach ( keys , ( key ) => {
5556 let descriptor ;
@@ -68,7 +69,7 @@ function TryGetAllProperties(object, target = object) {
6869 }
6970 }
7071 if ( key === 'cause' ) {
71- descriptor . value = serializeError ( descriptor . value ) ;
72+ descriptor . value = serializeError ( descriptor . value , rememberSet ) ;
7273 all [ key ] = descriptor ;
7374 } else if ( 'value' in descriptor &&
7475 typeof descriptor . value !== 'function' && typeof descriptor . value !== 'symbol' ) {
@@ -108,21 +109,27 @@ function inspect(...args) {
108109}
109110
110111let serialize ;
111- function serializeError ( error ) {
112+ function serializeError ( error , rememberSet = new SafeSet ( ) ) {
112113 serialize ??= require ( 'v8' ) . serialize ;
113114 if ( typeof error === 'symbol' ) {
114115 return Buffer . from ( StringFromCharCode ( kInspectedSymbol ) + inspect ( error ) , 'utf8' ) ;
115116 }
117+
116118 try {
117119 if ( typeof error === 'object' &&
118120 ObjectPrototypeToString ( error ) === '[object Error]' ) {
121+ if ( rememberSet . has ( error ) ) {
122+ return Buffer . from ( [ kCircularReference ] ) ;
123+ }
124+ rememberSet . add ( error ) ;
125+
119126 const constructors = GetConstructors ( error ) ;
120127 for ( let i = 0 ; i < constructors . length ; i ++ ) {
121128 const name = GetName ( constructors [ i ] ) ;
122129 if ( errorConstructorNames . has ( name ) ) {
123130 const serialized = serialize ( {
124131 constructor : name ,
125- properties : TryGetAllProperties ( error ) ,
132+ properties : TryGetAllProperties ( error , error , rememberSet ) ,
126133 } ) ;
127134 return Buffer . concat ( [ Buffer . from ( [ kSerializedError ] ) , serialized ] ) ;
128135 }
@@ -183,6 +190,11 @@ function deserializeError(error) {
183190 __proto__ : null ,
184191 [ customInspectSymbol ] : ( ) => fromBuffer ( error ) . toString ( 'utf8' ) ,
185192 } ;
193+ case kCircularReference :
194+ return {
195+ __proto__ : null ,
196+ [ customInspectSymbol ] : ( ) => '[Circular object]' ,
197+ } ;
186198 }
187199 require ( 'assert' ) . fail ( 'This should not happen' ) ;
188200}
0 commit comments