@@ -39,10 +39,15 @@ using node::TIME_TYPE;
3939using node::worker::Worker;
4040using v8::Array;
4141using v8::Context;
42+ using v8::HandleScope;
4243using v8::HeapSpaceStatistics;
4344using v8::HeapStatistics;
4445using v8::Isolate;
46+ using v8::Just;
4547using v8::Local;
48+ using v8::Maybe;
49+ using v8::MaybeLocal;
50+ using v8::Nothing;
4651using v8::Object;
4752using v8::String;
4853using v8::TryCatch;
@@ -58,16 +63,16 @@ static void WriteNodeReport(Isolate* isolate,
5863 const char * trigger,
5964 const std::string& filename,
6065 std::ostream& out,
61- Local<Object > error,
66+ Local<Value > error,
6267 bool compact);
6368static void PrintVersionInformation (JSONWriter* writer);
6469static void PrintJavaScriptErrorStack (JSONWriter* writer,
6570 Isolate* isolate,
66- Local<Object > error,
71+ Local<Value > error,
6772 const char * trigger);
6873static void PrintJavaScriptErrorProperties (JSONWriter* writer,
6974 Isolate* isolate,
70- Local<Object > error);
75+ Local<Value > error);
7176static void PrintNativeStack (JSONWriter* writer);
7277static void PrintResourceUsage (JSONWriter* writer);
7378static void PrintGCStatistics (JSONWriter* writer, Isolate* isolate);
@@ -84,7 +89,7 @@ std::string TriggerNodeReport(Isolate* isolate,
8489 const char * message,
8590 const char * trigger,
8691 const std::string& name,
87- Local<Object > error) {
92+ Local<Value > error) {
8893 std::string filename;
8994
9095 // Determine the required report filename. In order of priority:
@@ -169,7 +174,7 @@ void GetNodeReport(Isolate* isolate,
169174 Environment* env,
170175 const char * message,
171176 const char * trigger,
172- Local<Object > error,
177+ Local<Value > error,
173178 std::ostream& out) {
174179 WriteNodeReport (isolate, env, message, trigger, " " , out, error, false );
175180}
@@ -182,7 +187,7 @@ static void WriteNodeReport(Isolate* isolate,
182187 const char * trigger,
183188 const std::string& filename,
184189 std::ostream& out,
185- Local<Object > error,
190+ Local<Value > error,
186191 bool compact) {
187192 // Obtain the current time and the pid.
188193 TIME_TYPE tm_struct;
@@ -474,13 +479,14 @@ static void PrintNetworkInterfaceInfo(JSONWriter* writer) {
474479
475480static void PrintJavaScriptErrorProperties (JSONWriter* writer,
476481 Isolate* isolate,
477- Local<Object > error) {
482+ Local<Value > error) {
478483 writer->json_objectstart (" errorProperties" );
479- if (!error.IsEmpty ()) {
484+ if (!error.IsEmpty () && error-> IsObject () ) {
480485 TryCatch try_catch (isolate);
481- Local<Context> context = error->GetIsolate ()->GetCurrentContext ();
486+ Local<Object> error_obj = error.As <Object>();
487+ Local<Context> context = error_obj->GetIsolate ()->GetCurrentContext ();
482488 Local<Array> keys;
483- if (!error ->GetOwnPropertyNames (context).ToLocal (&keys)) {
489+ if (!error_obj ->GetOwnPropertyNames (context).ToLocal (&keys)) {
484490 return writer->json_objectend (); // the end of 'errorProperties'
485491 }
486492 uint32_t keys_length = keys->Length ();
@@ -491,7 +497,7 @@ static void PrintJavaScriptErrorProperties(JSONWriter* writer,
491497 }
492498 Local<Value> value;
493499 Local<String> value_string;
494- if (!error ->Get (context, key).ToLocal (&value) ||
500+ if (!error_obj ->Get (context, key).ToLocal (&value) ||
495501 !value->ToString (context).ToLocal (&value_string)) {
496502 continue ;
497503 }
@@ -505,26 +511,50 @@ static void PrintJavaScriptErrorProperties(JSONWriter* writer,
505511 writer->json_objectend (); // the end of 'errorProperties'
506512}
507513
514+ static Maybe<std::string> ErrorToString (Isolate* isolate,
515+ Local<Context> context,
516+ Local<Value> error) {
517+ if (error.IsEmpty ()) {
518+ return Nothing<std::string>();
519+ }
520+
521+ MaybeLocal<String> maybe_str;
522+ // `ToString` is not available to Symbols.
523+ if (error->IsSymbol ()) {
524+ maybe_str = error.As <v8::Symbol>()->ToDetailString (context);
525+ } else if (!error->IsObject ()) {
526+ maybe_str = error->ToString (context);
527+ } else if (error->IsObject ()) {
528+ MaybeLocal<Value> stack = error.As <Object>()->Get (
529+ context, node::FIXED_ONE_BYTE_STRING (isolate, " stack" ));
530+ if (!stack.IsEmpty () && stack.ToLocalChecked ()->IsString ()) {
531+ maybe_str = stack.ToLocalChecked ().As <String>();
532+ }
533+ }
534+
535+ Local<String> js_str;
536+ if (!maybe_str.ToLocal (&js_str)) {
537+ return Nothing<std::string>();
538+ }
539+ String::Utf8Value sv (isolate, js_str);
540+ return Just<>(std::string (*sv, sv.length ()));
541+ }
542+
508543// Report the JavaScript stack.
509544static void PrintJavaScriptErrorStack (JSONWriter* writer,
510- Isolate* isolate,
511- Local<Object> error,
512- const char * trigger) {
513- Local<Value> stackstr;
514- std::string ss = " " ;
545+ Isolate* isolate,
546+ Local<Value> error,
547+ const char * trigger) {
515548 TryCatch try_catch (isolate);
549+ HandleScope scope (isolate);
550+ Local<Context> context = isolate->GetCurrentContext ();
551+ std::string ss = " " ;
516552 if ((!strcmp (trigger, " FatalError" )) ||
517- (!strcmp (trigger, " Signal" ))) {
553+ (!strcmp (trigger, " Signal" )) ||
554+ (!ErrorToString (isolate, context, error).To (&ss))) {
518555 ss = " No stack.\n Unavailable.\n " ;
519- } else if (!error.IsEmpty () &&
520- error
521- ->Get (isolate->GetCurrentContext (),
522- node::FIXED_ONE_BYTE_STRING (isolate,
523- " stack" ))
524- .ToLocal (&stackstr)) {
525- String::Utf8Value sv (isolate, stackstr);
526- ss = std::string (*sv, sv.length ());
527556 }
557+
528558 int line = ss.find (' \n ' );
529559 if (line == -1 ) {
530560 writer->json_keyvalue (" message" , ss);
0 commit comments