@@ -37,6 +37,27 @@ std::string kindToString(const Value& v, Runtime* rt = nullptr) {
37
37
}
38
38
}
39
39
40
+ // getPropertyAsFunction() will try to create a JSError. If the
41
+ // failure is in building a JSError, this will lead to infinite
42
+ // recursion. This function is used in place of getPropertyAsFunction
43
+ // when building JSError, to avoid that infinite recursion.
44
+ Value callGlobalFunction (Runtime& runtime, const char * name, const Value& arg) {
45
+ Value v = runtime.global ().getProperty (runtime, name);
46
+ if (!v.isObject ()) {
47
+ throw JSINativeException (
48
+ std::string (" callGlobalFunction: JS global property '" ) + name +
49
+ " ' is " + kindToString (v, &runtime) + " , expected a Function" );
50
+ }
51
+ Object o = v.getObject (runtime);
52
+ if (!o.isFunction (runtime)) {
53
+ throw JSINativeException (
54
+ std::string (" callGlobalFunction: JS global property '" ) + name +
55
+ " ' is a non-callable Object, expected a Function" );
56
+ }
57
+ Function f = std::move (o).getFunction (runtime);
58
+ return f.call (runtime, arg);
59
+ }
60
+
40
61
} // namespace
41
62
42
63
namespace detail {
@@ -142,9 +163,7 @@ Function Object::getPropertyAsFunction(Runtime& runtime, const char* name)
142
163
kindToString (std::move (obj), &runtime) + " , expected a Function" );
143
164
};
144
165
145
- Runtime::PointerValue* value = obj.ptr_ ;
146
- obj.ptr_ = nullptr ;
147
- return Function (value);
166
+ return std::move (obj).getFunction (runtime);
148
167
}
149
168
150
169
Array Object::asArray (Runtime& runtime) const & {
@@ -347,7 +366,11 @@ JSError::JSError(Runtime& rt, Value&& value) {
347
366
JSError::JSError (Runtime& rt, std::string msg) : message_(std::move(msg)) {
348
367
try {
349
368
setValue (
350
- rt, rt.global ().getPropertyAsFunction (rt, " Error" ).call (rt, message_));
369
+ rt,
370
+ callGlobalFunction (rt, " Error" , String::createFromUtf8 (rt, message_)));
371
+ } catch (const std::exception & ex) {
372
+ message_ = std::string (ex.what ()) + " (while raising " + message_ + " )" ;
373
+ setValue (rt, String::createFromUtf8 (rt, message_));
351
374
} catch (...) {
352
375
setValue (rt, Value ());
353
376
}
@@ -360,6 +383,8 @@ JSError::JSError(Runtime& rt, std::string msg, std::string stack)
360
383
e.setProperty (rt, " message" , String::createFromUtf8 (rt, message_));
361
384
e.setProperty (rt, " stack" , String::createFromUtf8 (rt, stack_));
362
385
setValue (rt, std::move (e));
386
+ } catch (const std::exception & ex) {
387
+ setValue (rt, String::createFromUtf8 (rt, ex.what ()));
363
388
} catch (...) {
364
389
setValue (rt, Value ());
365
390
}
@@ -380,20 +405,23 @@ void JSError::setValue(Runtime& rt, Value&& value) {
380
405
if (message_.empty ()) {
381
406
jsi::Value message = obj.getProperty (rt, " message" );
382
407
if (!message.isUndefined ()) {
383
- message_ = message.toString (rt).utf8 (rt);
408
+ message_ =
409
+ callGlobalFunction (rt, " String" , message).getString (rt).utf8 (rt);
384
410
}
385
411
}
386
412
387
413
if (stack_.empty ()) {
388
414
jsi::Value stack = obj.getProperty (rt, " stack" );
389
415
if (!stack.isUndefined ()) {
390
- stack_ = stack.toString (rt).utf8 (rt);
416
+ stack_ =
417
+ callGlobalFunction (rt, " String" , stack).getString (rt).utf8 (rt);
391
418
}
392
419
}
393
420
}
394
421
395
422
if (message_.empty ()) {
396
- message_ = value_->toString (rt).utf8 (rt);
423
+ message_ =
424
+ callGlobalFunction (rt, " String" , *value_).getString (rt).utf8 (rt);
397
425
}
398
426
399
427
if (stack_.empty ()) {
@@ -403,6 +431,13 @@ void JSError::setValue(Runtime& rt, Value&& value) {
403
431
if (what_.empty ()) {
404
432
what_ = message_ + " \n\n " + stack_;
405
433
}
434
+ } catch (const std::exception & ex) {
435
+ message_ = std::string (" [Exception while creating message string: " ) +
436
+ ex.what () + " ]" ;
437
+ stack_ = std::string (" Exception while creating stack string: " ) +
438
+ ex.what () + " ]" ;
439
+ what_ =
440
+ std::string (" Exception while getting value fields: " ) + ex.what () + " ]" ;
406
441
} catch (...) {
407
442
message_ = " [Exception caught creating message string]" ;
408
443
stack_ = " [Exception caught creating stack string]" ;
0 commit comments