Skip to content

Commit 84358b5

Browse files
committed
src: handle errors while printing error objects
Handle situations where accessing `.name` or `.stack` on an object fails. Fixes: #25718 PR-URL: #25834 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Minwoo Jung <minwoo@nodesource.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent f027290 commit 84358b5

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

src/node_errors.cc

+18-17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace node {
1111

12+
using errors::TryCatchScope;
1213
using v8::Context;
1314
using v8::Exception;
1415
using v8::Function;
@@ -201,8 +202,10 @@ void ReportException(Environment* env,
201202
} else {
202203
Local<Object> err_obj = er->ToObject(env->context()).ToLocalChecked();
203204

204-
trace_value = err_obj->Get(env->context(),
205-
env->stack_string()).ToLocalChecked();
205+
if (!err_obj->Get(env->context(), env->stack_string())
206+
.ToLocal(&trace_value)) {
207+
trace_value = Undefined(env->isolate());
208+
}
206209
arrow =
207210
err_obj->GetPrivate(env->context(), env->arrow_message_private_symbol())
208211
.ToLocalChecked();
@@ -222,27 +225,25 @@ void ReportException(Environment* env,
222225
// this really only happens for RangeErrors, since they're the only
223226
// kind that won't have all this info in the trace, or when non-Error
224227
// objects are thrown manually.
225-
Local<Value> message;
226-
Local<Value> name;
228+
MaybeLocal<Value> message;
229+
MaybeLocal<Value> name;
227230

228231
if (er->IsObject()) {
229232
Local<Object> err_obj = er.As<Object>();
230-
message = err_obj->Get(env->context(),
231-
env->message_string()).ToLocalChecked();
232-
name = err_obj->Get(env->context(),
233-
FIXED_ONE_BYTE_STRING(env->isolate(), "name")).ToLocalChecked();
233+
message = err_obj->Get(env->context(), env->message_string());
234+
name = err_obj->Get(env->context(), env->name_string());
234235
}
235236

236-
if (message.IsEmpty() || message->IsUndefined() || name.IsEmpty() ||
237-
name->IsUndefined()) {
237+
if (message.IsEmpty() || message.ToLocalChecked()->IsUndefined() ||
238+
name.IsEmpty() || name.ToLocalChecked()->IsUndefined()) {
238239
// Not an error object. Just print as-is.
239240
String::Utf8Value message(env->isolate(), er);
240241

241242
PrintErrorString("%s\n",
242243
*message ? *message : "<toString() threw exception>");
243244
} else {
244-
node::Utf8Value name_string(env->isolate(), name);
245-
node::Utf8Value message_string(env->isolate(), message);
245+
node::Utf8Value name_string(env->isolate(), name.ToLocalChecked());
246+
node::Utf8Value message_string(env->isolate(), message.ToLocalChecked());
246247

247248
if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
248249
PrintErrorString("%s: %s\n", *name_string, *message_string);
@@ -681,8 +682,8 @@ void DecorateErrorStack(Environment* env,
681682
if (IsExceptionDecorated(env, err_obj)) return;
682683

683684
AppendExceptionLine(env, exception, try_catch.Message(), CONTEXTIFY_ERROR);
684-
Local<Value> stack =
685-
err_obj->Get(env->context(), env->stack_string()).ToLocalChecked();
685+
TryCatchScope try_catch_scope(env); // Ignore exceptions below.
686+
MaybeLocal<Value> stack = err_obj->Get(env->context(), env->stack_string());
686687
MaybeLocal<Value> maybe_value =
687688
err_obj->GetPrivate(env->context(), env->arrow_message_private_symbol());
688689

@@ -691,7 +692,7 @@ void DecorateErrorStack(Environment* env,
691692
return;
692693
}
693694

694-
if (stack.IsEmpty() || !stack->IsString()) {
695+
if (stack.IsEmpty() || !stack.ToLocalChecked()->IsString()) {
695696
return;
696697
}
697698

@@ -700,8 +701,8 @@ void DecorateErrorStack(Environment* env,
700701
String::Concat(env->isolate(),
701702
arrow.As<String>(),
702703
FIXED_ONE_BYTE_STRING(env->isolate(), "\n")),
703-
stack.As<String>());
704-
err_obj->Set(env->context(), env->stack_string(), decorated_stack).FromJust();
704+
stack.ToLocalChecked().As<String>());
705+
USE(err_obj->Set(env->context(), env->stack_string(), decorated_stack));
705706
err_obj->SetPrivate(
706707
env->context(), env->decorated_private_symbol(), True(env->isolate()));
707708
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict';
2+
require('../common');
3+
throw { // eslint-disable-line no-throw-literal
4+
get stack() {
5+
throw new Error('weird throw but ok');
6+
},
7+
get name() {
8+
throw new Error('weird throw but ok');
9+
},
10+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
*:3
3+
throw { // eslint-disable-line no-throw-literal
4+
^
5+
[object Object]

0 commit comments

Comments
 (0)