File tree 3 files changed +49
-4
lines changed
3 files changed +49
-4
lines changed Original file line number Diff line number Diff line change 1
1
'use strict' ;
2
2
3
+ const { safeToString } = process . binding ( 'util' ) ;
4
+
3
5
const promiseRejectEvent = process . _promiseRejectEvent ;
4
6
const hasBeenNotifiedProperty = new WeakMap ( ) ;
5
7
const promiseToGuidProperty = new WeakMap ( ) ;
@@ -64,12 +66,17 @@ function setupPromises(scheduleMicrotasks) {
64
66
hasBeenNotifiedProperty . set ( promise , true ) ;
65
67
const uid = promiseToGuidProperty . get ( promise ) ;
66
68
if ( ! process . emit ( 'unhandledRejection' , reason , promise ) ) {
67
- const warning = new Error ( 'Unhandled promise rejection ' +
68
- `(rejection id: ${ uid } ): ${ reason } ` ) ;
69
+ const warning = new Error (
70
+ `Unhandled promise rejection (rejection id: ${ uid } ): ` +
71
+ safeToString ( reason ) ) ;
69
72
warning . name = 'UnhandledPromiseRejectionWarning' ;
70
73
warning . id = uid ;
71
- if ( reason instanceof Error ) {
72
- warning . stack = reason . stack ;
74
+ try {
75
+ if ( reason instanceof Error ) {
76
+ warning . stack = reason . stack ;
77
+ }
78
+ } catch ( err ) {
79
+ // ignored
73
80
}
74
81
process . emitWarning ( warning ) ;
75
82
} else {
Original file line number Diff line number Diff line change @@ -54,6 +54,12 @@ static void GetProxyDetails(const FunctionCallbackInfo<Value>& args) {
54
54
args.GetReturnValue ().Set (ret);
55
55
}
56
56
57
+ // Side effect-free stringification that will never throw exceptions.
58
+ static void SafeToString (const FunctionCallbackInfo<Value>& args) {
59
+ auto context = args.GetIsolate ()->GetCurrentContext ();
60
+ args.GetReturnValue ().Set (args[0 ]->ToDetailString (context).ToLocalChecked ());
61
+ }
62
+
57
63
static void GetHiddenValue (const FunctionCallbackInfo<Value>& args) {
58
64
Environment* env = Environment::GetCurrent (args);
59
65
@@ -122,6 +128,7 @@ void Initialize(Local<Object> target,
122
128
env->SetMethod (target, " getHiddenValue" , GetHiddenValue);
123
129
env->SetMethod (target, " setHiddenValue" , SetHiddenValue);
124
130
env->SetMethod (target, " getProxyDetails" , GetProxyDetails);
131
+ env->SetMethod (target, " safeToString" , SafeToString);
125
132
126
133
env->SetMethod (target, " startSigintWatchdog" , StartSigintWatchdog);
127
134
env->SetMethod (target, " stopSigintWatchdog" , StopSigintWatchdog);
Original file line number Diff line number Diff line change
1
+ 'use strict' ;
2
+ const common = require ( '../common' ) ;
3
+
4
+ const expectedPromiseWarning = 'Unhandled promise rejection (rejection id: ' +
5
+ '1): [object Object]' ;
6
+
7
+ function throwErr ( ) {
8
+ throw new Error ( 'Error from proxy' ) ;
9
+ }
10
+
11
+ const thorny = new Proxy ( { } , {
12
+ getPrototypeOf : throwErr ,
13
+ setPrototypeOf : throwErr ,
14
+ isExtensible : throwErr ,
15
+ preventExtensions : throwErr ,
16
+ getOwnPropertyDescriptor : throwErr ,
17
+ defineProperty : throwErr ,
18
+ has : throwErr ,
19
+ get : throwErr ,
20
+ set : throwErr ,
21
+ deleteProperty : throwErr ,
22
+ ownKeys : throwErr ,
23
+ apply : throwErr ,
24
+ construct : throwErr
25
+ } ) ;
26
+
27
+ common . expectWarning ( 'UnhandledPromiseRejectionWarning' ,
28
+ expectedPromiseWarning ) ;
29
+
30
+ // ensure this doesn't crash
31
+ Promise . reject ( thorny ) ;
You can’t perform that action at this time.
0 commit comments