Skip to content

Commit 5202b84

Browse files
joyeecheungdanielleadams
authored andcommitted
bootstrap: print stack trace during environment creation failure
#45888 took the environment creation code out of the scope covered by the v8::TryCatch that we use to print early failures during environment creation. So e.g. when adding something that would fail in node.js, we get ``` node:internal/options:554: Uncaught Error: Should not query options before bootstrapping is done ``` This patch restores that by adding another v8::TryCatch for it: ``` node:internal/options:20 ({ options: optionsMap } = getCLIOptions()); ^ Error: Should not query options before bootstrapping is done at getCLIOptionsFromBinding (node:internal/options:20:32) at getOptionValue (node:internal/options:45:19) at node:internal/bootstrap/node:433:29 ``` PR-URL: #46533 Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent 307d096 commit 5202b84

File tree

3 files changed

+69
-25
lines changed

3 files changed

+69
-25
lines changed

src/api/embed_helpers.cc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ using v8::Locker;
1212
using v8::Maybe;
1313
using v8::Nothing;
1414
using v8::SealHandleScope;
15+
using v8::TryCatch;
1516

1617
namespace node {
1718

@@ -109,10 +110,19 @@ CommonEnvironmentSetup::CommonEnvironmentSetup(
109110
{
110111
Locker locker(isolate);
111112
Isolate::Scope isolate_scope(isolate);
113+
HandleScope handle_scope(isolate);
114+
115+
TryCatch bootstrapCatch(isolate);
116+
auto print_Exception = OnScopeLeave([&]() {
117+
if (bootstrapCatch.HasCaught()) {
118+
errors->push_back(FormatCaughtException(
119+
isolate, isolate->GetCurrentContext(), bootstrapCatch));
120+
}
121+
});
122+
112123
impl_->isolate_data.reset(CreateIsolateData(
113124
isolate, loop, platform, impl_->allocator.get()));
114125

115-
HandleScope handle_scope(isolate);
116126
Local<Context> context = NewContext(isolate);
117127
impl_->context.Reset(isolate, context);
118128
if (context.IsEmpty()) {

src/node_errors.cc

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,8 @@ static std::string GetErrorSource(Isolate* isolate,
185185
return buf + std::string(underline_buf, off);
186186
}
187187

188-
void PrintStackTrace(Isolate* isolate, Local<StackTrace> stack) {
188+
static std::string FormatStackTrace(Isolate* isolate, Local<StackTrace> stack) {
189+
std::string result;
189190
for (int i = 0; i < stack->GetFrameCount(); i++) {
190191
Local<StackFrame> stack_frame = stack->GetFrame(isolate, i);
191192
node::Utf8Value fn_name_s(isolate, stack_frame->GetFunctionName());
@@ -195,53 +196,82 @@ void PrintStackTrace(Isolate* isolate, Local<StackTrace> stack) {
195196

196197
if (stack_frame->IsEval()) {
197198
if (stack_frame->GetScriptId() == Message::kNoScriptIdInfo) {
198-
FPrintF(stderr, " at [eval]:%i:%i\n", line_number, column);
199+
result += SPrintF(" at [eval]:%i:%i\n", line_number, column);
199200
} else {
200-
FPrintF(stderr,
201-
" at [eval] (%s:%i:%i)\n",
202-
*script_name,
203-
line_number,
204-
column);
201+
std::vector<char> buf(script_name.length() + 64);
202+
snprintf(buf.data(),
203+
buf.size(),
204+
" at [eval] (%s:%i:%i)\n",
205+
*script_name,
206+
line_number,
207+
column);
208+
result += std::string(buf.data());
205209
}
206210
break;
207211
}
208212

209213
if (fn_name_s.length() == 0) {
210-
FPrintF(stderr, " at %s:%i:%i\n", script_name, line_number, column);
214+
std::vector<char> buf(script_name.length() + 64);
215+
snprintf(buf.data(),
216+
buf.size(),
217+
" at %s:%i:%i\n",
218+
*script_name,
219+
line_number,
220+
column);
221+
result += std::string(buf.data());
211222
} else {
212-
FPrintF(stderr,
213-
" at %s (%s:%i:%i)\n",
214-
fn_name_s,
215-
script_name,
216-
line_number,
217-
column);
223+
std::vector<char> buf(fn_name_s.length() + script_name.length() + 64);
224+
snprintf(buf.data(),
225+
buf.size(),
226+
" at %s (%s:%i:%i)\n",
227+
*fn_name_s,
228+
*script_name,
229+
line_number,
230+
column);
231+
result += std::string(buf.data());
218232
}
219233
}
234+
return result;
235+
}
236+
237+
static void PrintToStderrAndFlush(const std::string& str) {
238+
FPrintF(stderr, "%s\n", str);
220239
fflush(stderr);
221240
}
222241

223-
void PrintException(Isolate* isolate,
224-
Local<Context> context,
225-
Local<Value> err,
226-
Local<Message> message) {
242+
void PrintStackTrace(Isolate* isolate, Local<StackTrace> stack) {
243+
PrintToStderrAndFlush(FormatStackTrace(isolate, stack));
244+
}
245+
246+
std::string FormatCaughtException(Isolate* isolate,
247+
Local<Context> context,
248+
Local<Value> err,
249+
Local<Message> message) {
227250
node::Utf8Value reason(isolate,
228251
err->ToDetailString(context)
229252
.FromMaybe(Local<String>()));
230253
bool added_exception_line = false;
231254
std::string source =
232255
GetErrorSource(isolate, context, message, &added_exception_line);
233-
FPrintF(stderr, "%s\n", source);
234-
FPrintF(stderr, "%s\n", reason);
256+
std::string result = source + '\n' + reason.ToString() + '\n';
235257

236258
Local<v8::StackTrace> stack = message->GetStackTrace();
237-
if (!stack.IsEmpty()) PrintStackTrace(isolate, stack);
259+
if (!stack.IsEmpty()) result += FormatStackTrace(isolate, stack);
260+
return result;
261+
}
262+
263+
std::string FormatCaughtException(Isolate* isolate,
264+
Local<Context> context,
265+
const v8::TryCatch& try_catch) {
266+
CHECK(try_catch.HasCaught());
267+
return FormatCaughtException(
268+
isolate, context, try_catch.Exception(), try_catch.Message());
238269
}
239270

240271
void PrintCaughtException(Isolate* isolate,
241272
Local<Context> context,
242273
const v8::TryCatch& try_catch) {
243-
CHECK(try_catch.HasCaught());
244-
PrintException(isolate, context, try_catch.Exception(), try_catch.Message());
274+
PrintToStderrAndFlush(FormatCaughtException(isolate, context, try_catch));
245275
}
246276

247277
void AppendExceptionLine(Environment* env,
@@ -1076,7 +1106,8 @@ void TriggerUncaughtException(Isolate* isolate,
10761106
// error is supposed to be thrown at this point.
10771107
// Since we don't have access to Environment here, there is not
10781108
// much we can do, so we just print whatever is useful and crash.
1079-
PrintException(isolate, context, error, message);
1109+
PrintToStderrAndFlush(
1110+
FormatCaughtException(isolate, context, error, message));
10801111
Abort();
10811112
}
10821113

src/node_internals.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ void PrintStackTrace(v8::Isolate* isolate, v8::Local<v8::StackTrace> stack);
8383
void PrintCaughtException(v8::Isolate* isolate,
8484
v8::Local<v8::Context> context,
8585
const v8::TryCatch& try_catch);
86+
std::string FormatCaughtException(v8::Isolate* isolate,
87+
v8::Local<v8::Context> context,
88+
const v8::TryCatch& try_catch);
8689

8790
void ResetStdio(); // Safe to call more than once and from signal handlers.
8891
#ifdef __POSIX__

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy