@@ -186,9 +186,13 @@ fn clone_regexp(
186186
187187fn clone_error (
188188 original : & JsObject ,
189+ transfer : & HashSet < JsObject > ,
189190 seen : & mut SeenMap ,
190191 context : & mut Context ,
191192) -> JsResult < JsValueStore > {
193+ let mut store = JsValueStore :: empty ( ) ;
194+ seen. insert ( original, store. clone ( ) ) ;
195+
192196 let native = JsError :: from_opaque ( JsValue :: from ( original. clone ( ) ) )
193197 . try_native ( context)
194198 . map_err ( |_| unsupported_type ( ) ) ?;
@@ -215,17 +219,51 @@ fn clone_error(
215219
216220 let name = to_optional_string ( "name" , context) ?;
217221 let stack = to_optional_string ( "stack" , context) ?;
218- let cause = to_optional_string ( "cause" , context) ?;
219-
220- let stored = JsValueStore :: new ( ValueStoreInner :: Error {
221- kind,
222- name : name. into ( ) ,
223- message : JsString :: from ( native. message ( ) ) . into ( ) ,
224- stack : stack. into ( ) ,
225- cause : cause. into ( ) ,
226- } ) ;
227- seen. insert ( original, stored. clone ( ) ) ;
228- Ok ( stored)
222+
223+ let cause = if original. has_own_property ( js_string ! ( "cause" ) , context) ? {
224+ let cause = original. get ( js_string ! ( "cause" ) , context) ?;
225+ Some ( try_from_js_value ( & cause, transfer, seen, context) ?)
226+ } else {
227+ None
228+ } ;
229+
230+ let errors = if matches ! ( kind, ErrorKind :: Aggregate ) {
231+ let errors = original. get ( js_string ! ( "errors" ) , context) ?;
232+ if errors. is_undefined ( ) {
233+ Vec :: new ( )
234+ } else {
235+ let Some ( errors) = errors. as_object ( ) else {
236+ return Err ( unsupported_type ( ) ) ;
237+ } ;
238+
239+ let errors = JsArray :: from_object ( errors) . map_err ( |_| unsupported_type ( ) ) ?;
240+
241+ let length = errors. length ( context) ?;
242+ let length = usize:: try_from ( length) . map_err ( JsError :: from_rust) ?;
243+ let mut values = Vec :: with_capacity ( length) ;
244+ for i in 0 ..length {
245+ let value = errors. get ( i, context) ?;
246+ values. push ( try_from_js_value ( & value, transfer, seen, context) ?) ;
247+ }
248+ values
249+ }
250+ } else {
251+ Vec :: new ( )
252+ } ;
253+
254+ // SAFETY: This is safe as this function is the sole owner of the store.
255+ unsafe {
256+ store. replace ( ValueStoreInner :: Error {
257+ kind,
258+ name : name. into ( ) ,
259+ message : JsString :: from ( native. message ( ) ) . into ( ) ,
260+ stack : stack. into ( ) ,
261+ cause,
262+ errors,
263+ } ) ;
264+ }
265+
266+ Ok ( store)
229267}
230268
231269fn try_from_map (
@@ -306,7 +344,7 @@ fn try_from_js_object_clone(
306344 } else if let Ok ( ref date) = JsDate :: from_object ( object. clone ( ) ) {
307345 return clone_date ( object, date, seen, context) ;
308346 } else if object. downcast_ref :: < Error > ( ) . is_some ( ) {
309- return clone_error ( object, seen, context) ;
347+ return clone_error ( object, transfer , seen, context) ;
310348 } else if let Ok ( ref regexp) = JsRegExp :: from_object ( object. clone ( ) ) {
311349 return clone_regexp ( object, regexp, seen, context) ;
312350 } else if let Ok ( _dataview) = JsDataView :: from_object ( object. clone ( ) ) {
0 commit comments