| 502 | } |
| 503 | |
| 504 | static std::string format_exception_log_message(JSContext* cx, |
| 505 | JS::HandleValue exc, |
| 506 | JS::HandleString message) { |
| 507 | std::ostringstream out; |
| 508 | |
| 509 | if (message) { |
| 510 | JS::UniqueChars utf8_message = JS_EncodeStringToUTF8(cx, message); |
| 511 | log_exception_brief(cx); |
| 512 | if (utf8_message) |
| 513 | out << utf8_message.get() << ": "; |
| 514 | } |
| 515 | |
| 516 | JS::RootedString exc_str(cx, exception_to_string(cx, exc)); |
| 517 | if (exc_str) { |
| 518 | JS::UniqueChars utf8_exception = JS_EncodeStringToUTF8(cx, exc_str); |
| 519 | if (utf8_exception) |
| 520 | out << utf8_exception.get(); |
| 521 | } |
| 522 | log_exception_brief(cx); |
| 523 | |
| 524 | if (!exc.isObject()) |
| 525 | return out.str(); |
| 526 | |
| 527 | JS::RootedObject exc_obj(cx, &exc.toObject()); |
| 528 | const JSClass* syntax_error = js::ProtoKeyToClass(JSProto_SyntaxError); |
| 529 | if (JS_InstanceOf(cx, exc_obj, syntax_error, nullptr)) { |
| 530 | // We log syntax errors differently, because the stack for those |
| 531 | // includes only the referencing module, but we want to print out the |
| 532 | // file name, line number, and column number from the exception. |
| 533 | // We assume that syntax errors have no cause property, and are not the |
| 534 | // cause of other exceptions, so no recursion. |
| 535 | out << format_syntax_error_location(cx, exc_obj) |
| 536 | << format_exception_stack(cx, exc_obj); |
| 537 | return out.str(); |
| 538 | } |
| 539 | |
| 540 | JS::Rooted<CauseSet> seen_causes(cx); |
| 541 | seen_causes.putNew(exc_obj); |
| 542 | out << format_exception_with_cause(cx, exc_obj, &seen_causes); |
| 543 | return out.str(); |
| 544 | } |
| 545 | |
| 546 | /** |
| 547 | * gjs_log_exception_full: |
no test coverage detected