GeezerVison is showing github.com — module: mark evaluation rejection in require(esm) as handled · nodejs/node@28a11ad
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: src/module_wrap.cc +16Lines changed: 16 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -663,6 +663,22 @@ void ModuleWrap::EvaluateSync(const FunctionCallbackInfo<Value>& args) { | 663 | 663 | CHECK(result->IsPromise()); | 664 | 664 | Local<Promise> promise = result.As<Promise>(); | 665 | 665 | if (promise->State() == Promise::PromiseState::kRejected) { | | 666 | + // The rejected promise is created by V8, so we don't get a chance to mark | | 667 | + // it as resolved before the rejection happens from evaluation. But we can | | 668 | + // tell the promise rejection callback to treat it as a promise rejected | | 669 | + // before handler was added which would remove it from the unhandled | | 670 | + // rejection handling, since we are converting it into an error and throw | | 671 | + // from here directly. | | 672 | + Local<Value> type = v8::Integer::New( | | 673 | + isolate, | | 674 | + static_cast<int32_t>( | | 675 | + v8::PromiseRejectEvent::kPromiseHandlerAddedAfterReject)); | | 676 | + Local<Value> args[] = {type, promise, Undefined(isolate)}; | | 677 | + if (env->promise_reject_callback() | | 678 | + ->Call(context, Undefined(isolate), arraysize(args), args) | | 679 | + .IsEmpty()) { | | 680 | + return; | | 681 | + } | 666 | 682 | Local<Value> exception = promise->Result(); | 667 | 683 | Local<v8::Message> message = | 668 | 684 | v8::Exception::CreateMessage(isolate, exception); | |
Collapse file Copy file name to clipboard +21Lines changed: 21 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// This tests synchronous errors in ESM from require(esm) can be caught. | | 2 | + | | 3 | +'use strict'; | | 4 | + | | 5 | +require('../common'); | | 6 | +const assert = require('assert'); | | 7 | + | | 8 | +// Runtime errors from throw should be caught. | | 9 | +assert.throws(() => { | | 10 | + require('../fixtures/es-modules/runtime-error-esm.js'); | | 11 | +}, { | | 12 | + message: 'hello' | | 13 | +}); | | 14 | + | | 15 | +// References errors should be caught too. | | 16 | +assert.throws(() => { | | 17 | + require('../fixtures/es-modules/reference-error-esm.js'); | | 18 | +}, { | | 19 | + name: 'ReferenceError', | | 20 | + message: 'exports is not defined' | | 21 | +}); |
Collapse file Copy file name to clipboard +13Lines changed: 13 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// This synchronous rejections from require(esm) still go to the unhandled rejection | | 2 | +// handler. | | 3 | + | | 4 | +'use strict'; | | 5 | + | | 6 | +const common = require('../common'); | | 7 | +const assert = require('assert'); | | 8 | + | | 9 | +process.on('unhandledRejection', common.mustCall((reason, promise) => { | | 10 | + assert.strictEqual(reason, 'reject!'); | | 11 | +})); | | 12 | + | | 13 | +require('../fixtures/es-modules/synchronous-rejection-esm.js'); |
Collapse file Copy file name to clipboard +5Lines changed: 5 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// This module is invalid in both ESM and CJS, because | | 2 | +// 'exports' are not defined in ESM, while require cannot be | | 3 | +// redeclared in CJS. | | 4 | +Object.defineProperty(exports, "__esModule", { value: true }); | | 5 | +const require = () => {}; |
Collapse file Copy file name to clipboard +2Lines changed: 2 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import 'node:fs'; // Forces it to be recognized as ESM. | | 2 | +throw new Error('hello'); |
Collapse file Copy file name to clipboard +2Lines changed: 2 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import 'node:fs'; // Forces it to be recognized as ESM. | | 2 | +Promise.reject('reject!'); |
|