@@ -108,15 +108,15 @@ function getDeterministicOption (options) {
108108 return value === undefined ? true : value
109109}
110110
111- function getBooleanOption ( options , key ) {
111+ function getBooleanOption ( options , key , defaultValue = true ) {
112112 let value
113113 if ( hasOwnProperty . call ( options , key ) ) {
114114 value = options [ key ]
115115 if ( typeof value !== 'boolean' ) {
116116 throw new TypeError ( `The "${ key } " argument must be of type boolean` )
117117 }
118118 }
119- return value === undefined ? true : value
119+ return value === undefined ? defaultValue : value
120120}
121121
122122function getPositiveIntegerOption ( options , key ) {
@@ -169,6 +169,19 @@ function getStrictOption (options) {
169169 }
170170}
171171
172+ function makeSafe ( method ) {
173+ return function ( ...input ) {
174+ try {
175+ return method ( ...input )
176+ } catch ( error ) {
177+ const message = typeof error ?. message === 'string'
178+ ? error . message
179+ : ( ( ) => { try { return String ( error ) } catch { return 'Failed' } } ) ( )
180+ return strEscape ( 'Error: Stringification failed. Message: ' + message )
181+ }
182+ }
183+ }
184+
172185function configure ( options ) {
173186 options = { ...options }
174187 const fail = getStrictOption ( options )
@@ -186,8 +199,9 @@ function configure (options) {
186199 const comparator = typeof deterministic === 'function' ? deterministic : undefined
187200 const maximumDepth = getPositiveIntegerOption ( options , 'maximumDepth' )
188201 const maximumBreadth = getPositiveIntegerOption ( options , 'maximumBreadth' )
202+ const safe = getBooleanOption ( options , 'safe' , false )
189203
190- function stringifyFnReplacer ( key , parent , stack , replacer , spacer , indentation ) {
204+ let stringifyFnReplacer = function ( key , parent , stack , replacer , spacer , indentation ) {
191205 let value = parent [ key ]
192206
193207 if ( typeof value === 'object' && value !== null && typeof value . toJSON === 'function' ) {
@@ -298,7 +312,7 @@ function configure (options) {
298312 }
299313 }
300314
301- function stringifyArrayReplacer ( key , value , stack , replacer , spacer , indentation ) {
315+ let stringifyArrayReplacer = function ( key , value , stack , replacer , spacer , indentation ) {
302316 if ( typeof value === 'object' && value !== null && typeof value . toJSON === 'function' ) {
303317 value = value . toJSON ( key )
304318 }
@@ -387,7 +401,7 @@ function configure (options) {
387401 }
388402 }
389403
390- function stringifyIndent ( key , value , stack , spacer , indentation ) {
404+ let stringifyIndent = function ( key , value , stack , spacer , indentation ) {
391405 switch ( typeof value ) {
392406 case 'string' :
393407 return strEscape ( value )
@@ -497,7 +511,7 @@ function configure (options) {
497511 }
498512 }
499513
500- function stringifySimple ( key , value , stack ) {
514+ let stringifySimple = function ( key , value , stack ) {
501515 switch ( typeof value ) {
502516 case 'string' :
503517 return strEscape ( value )
@@ -598,6 +612,13 @@ function configure (options) {
598612 }
599613 }
600614
615+ if ( safe ) {
616+ stringifyFnReplacer = makeSafe ( stringifyFnReplacer )
617+ stringifyArrayReplacer = makeSafe ( stringifyArrayReplacer )
618+ stringifyIndent = makeSafe ( stringifyIndent )
619+ stringifySimple = makeSafe ( stringifySimple )
620+ }
621+
601622 function stringify ( value , replacer , space ) {
602623 if ( arguments . length > 1 ) {
603624 let spacer = ''
0 commit comments