@@ -39,10 +39,15 @@ using node::TIME_TYPE;
39
39
using node::worker::Worker;
40
40
using v8::Array;
41
41
using v8::Context;
42
+ using v8::HandleScope;
42
43
using v8::HeapSpaceStatistics;
43
44
using v8::HeapStatistics;
44
45
using v8::Isolate;
46
+ using v8::Just;
45
47
using v8::Local;
48
+ using v8::Maybe;
49
+ using v8::MaybeLocal;
50
+ using v8::Nothing;
46
51
using v8::Object;
47
52
using v8::String;
48
53
using v8::TryCatch;
@@ -58,16 +63,16 @@ static void WriteNodeReport(Isolate* isolate,
58
63
const char * trigger,
59
64
const std::string& filename,
60
65
std::ostream& out,
61
- Local<Object > error,
66
+ Local<Value > error,
62
67
bool compact);
63
68
static void PrintVersionInformation (JSONWriter* writer);
64
69
static void PrintJavaScriptErrorStack (JSONWriter* writer,
65
70
Isolate* isolate,
66
- Local<Object > error,
71
+ Local<Value > error,
67
72
const char * trigger);
68
73
static void PrintJavaScriptErrorProperties (JSONWriter* writer,
69
74
Isolate* isolate,
70
- Local<Object > error);
75
+ Local<Value > error);
71
76
static void PrintNativeStack (JSONWriter* writer);
72
77
static void PrintResourceUsage (JSONWriter* writer);
73
78
static void PrintGCStatistics (JSONWriter* writer, Isolate* isolate);
@@ -84,7 +89,7 @@ std::string TriggerNodeReport(Isolate* isolate,
84
89
const char * message,
85
90
const char * trigger,
86
91
const std::string& name,
87
- Local<Object > error) {
92
+ Local<Value > error) {
88
93
std::string filename;
89
94
90
95
// Determine the required report filename. In order of priority:
@@ -169,7 +174,7 @@ void GetNodeReport(Isolate* isolate,
169
174
Environment* env,
170
175
const char * message,
171
176
const char * trigger,
172
- Local<Object > error,
177
+ Local<Value > error,
173
178
std::ostream& out) {
174
179
WriteNodeReport (isolate, env, message, trigger, " " , out, error, false );
175
180
}
@@ -182,7 +187,7 @@ static void WriteNodeReport(Isolate* isolate,
182
187
const char * trigger,
183
188
const std::string& filename,
184
189
std::ostream& out,
185
- Local<Object > error,
190
+ Local<Value > error,
186
191
bool compact) {
187
192
// Obtain the current time and the pid.
188
193
TIME_TYPE tm_struct;
@@ -474,13 +479,14 @@ static void PrintNetworkInterfaceInfo(JSONWriter* writer) {
474
479
475
480
static void PrintJavaScriptErrorProperties (JSONWriter* writer,
476
481
Isolate* isolate,
477
- Local<Object > error) {
482
+ Local<Value > error) {
478
483
writer->json_objectstart (" errorProperties" );
479
- if (!error.IsEmpty ()) {
484
+ if (!error.IsEmpty () && error-> IsObject () ) {
480
485
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 ();
482
488
Local<Array> keys;
483
- if (!error ->GetOwnPropertyNames (context).ToLocal (&keys)) {
489
+ if (!error_obj ->GetOwnPropertyNames (context).ToLocal (&keys)) {
484
490
return writer->json_objectend (); // the end of 'errorProperties'
485
491
}
486
492
uint32_t keys_length = keys->Length ();
@@ -491,7 +497,7 @@ static void PrintJavaScriptErrorProperties(JSONWriter* writer,
491
497
}
492
498
Local<Value> value;
493
499
Local<String> value_string;
494
- if (!error ->Get (context, key).ToLocal (&value) ||
500
+ if (!error_obj ->Get (context, key).ToLocal (&value) ||
495
501
!value->ToString (context).ToLocal (&value_string)) {
496
502
continue ;
497
503
}
@@ -505,26 +511,50 @@ static void PrintJavaScriptErrorProperties(JSONWriter* writer,
505
511
writer->json_objectend (); // the end of 'errorProperties'
506
512
}
507
513
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
+
508
543
// Report the JavaScript stack.
509
544
static 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) {
515
548
TryCatch try_catch (isolate);
549
+ HandleScope scope (isolate);
550
+ Local<Context> context = isolate->GetCurrentContext ();
551
+ std::string ss = " " ;
516
552
if ((!strcmp (trigger, " FatalError" )) ||
517
- (!strcmp (trigger, " Signal" ))) {
553
+ (!strcmp (trigger, " Signal" )) ||
554
+ (!ErrorToString (isolate, context, error).To (&ss))) {
518
555
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 ());
527
556
}
557
+
528
558
int line = ss.find (' \n ' );
529
559
if (line == -1 ) {
530
560
writer->json_keyvalue (" message" , ss);
0 commit comments