diff --git a/src/env-inl.h b/src/env-inl.h index a78ed024d2bbf9..e8943ffaf5af38 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -302,15 +302,18 @@ inline Environment* Environment::GetCurrent(v8::Isolate* isolate) { } inline Environment* Environment::GetCurrent(v8::Local context) { - if (UNLIKELY(context.IsEmpty() || - context->GetNumberOfEmbedderDataFields() < - ContextEmbedderIndex::kContextTag || - context->GetAlignedPointerFromEmbedderData( - ContextEmbedderIndex::kContextTag) != - Environment::kNodeContextTagPtr)) { + if (UNLIKELY(context.IsEmpty())) { + return nullptr; + } + if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <= + ContextEmbedderIndex::kContextTag)) { + return nullptr; + } + if (UNLIKELY(context->GetAlignedPointerFromEmbedderData( + ContextEmbedderIndex::kContextTag) != + Environment::kNodeContextTagPtr)) { return nullptr; } - return static_cast( context->GetAlignedPointerFromEmbedderData( ContextEmbedderIndex::kEnvironment)); diff --git a/src/node_errors.cc b/src/node_errors.cc index 3c04152974339e..7f134d236404e7 100644 --- a/src/node_errors.cc +++ b/src/node_errors.cc @@ -6,6 +6,7 @@ #ifdef NODE_REPORT #include "node_report.h" #endif +#include "node_v8_platform-inl.h" namespace node { @@ -170,13 +171,10 @@ void PrintStackTrace(Isolate* isolate, Local stack) { fflush(stderr); } -void PrintCaughtException(Isolate* isolate, - Local context, - const v8::TryCatch& try_catch) { - CHECK(try_catch.HasCaught()); - Local err = try_catch.Exception(); - Local message = try_catch.Message(); - Local stack = message->GetStackTrace(); +void PrintException(Isolate* isolate, + Local context, + Local err, + Local message) { node::Utf8Value reason(isolate, err->ToDetailString(context).ToLocalChecked()); bool added_exception_line = false; @@ -184,7 +182,16 @@ void PrintCaughtException(Isolate* isolate, GetErrorSource(isolate, context, message, &added_exception_line); fprintf(stderr, "%s\n", source.c_str()); fprintf(stderr, "%s\n", *reason); - PrintStackTrace(isolate, stack); + + Local stack = message->GetStackTrace(); + if (!stack.IsEmpty()) PrintStackTrace(isolate, stack); +} + +void PrintCaughtException(Isolate* isolate, + Local context, + const v8::TryCatch& try_catch) { + CHECK(try_catch.HasCaught()); + PrintException(isolate, context, try_catch.Exception(), try_catch.Message()); } void AppendExceptionLine(Environment* env, @@ -775,8 +782,20 @@ void FatalException(Isolate* isolate, CHECK(!error.IsEmpty()); HandleScope scope(isolate); - Environment* env = Environment::GetCurrent(isolate); - CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here. + CHECK(isolate->InContext()); + Local context = isolate->GetCurrentContext(); + Environment* env = Environment::GetCurrent(context); + if (env == nullptr) { + // This means that the exception happens before Environment is assigned + // to the context e.g. when there is a SyntaxError in a per-context + // script - which usually indicates that there is a bug because no JS + // error is supposed to be thrown at this point. + // Since we don't have access to Environment here, there is not + // much we can do, so we just print whatever useful and crash. + PrintException(isolate, context, error, message); + Abort(); + } + Local process_object = env->process_object(); Local fatal_exception_string = env->fatal_exception_string(); Local fatal_exception_function =