GeezerVison is showing github.com — module: mark evaluation rejection in require(esm) as handled · nodejs/node@3d89e6b
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 |
|---|
@@ -609,6 +609,22 @@ void ModuleWrap::EvaluateSync(const FunctionCallbackInfo<Value>& args) { | 609 | 609 | CHECK(result->IsPromise()); | 610 | 610 | Local<Promise> promise = result.As<Promise>(); | 611 | 611 | if (promise->State() == Promise::PromiseState::kRejected) { | | 612 | + // The rejected promise is created by V8, so we don't get a chance to mark | | 613 | + // it as resolved before the rejection happens from evaluation. But we can | | 614 | + // tell the promise rejection callback to treat it as a promise rejected | | 615 | + // before handler was added which would remove it from the unhandled | | 616 | + // rejection handling, since we are converting it into an error and throw | | 617 | + // from here directly. | | 618 | + Local<Value> type = v8::Integer::New( | | 619 | + isolate, | | 620 | + static_cast<int32_t>( | | 621 | + v8::PromiseRejectEvent::kPromiseHandlerAddedAfterReject)); | | 622 | + Local<Value> args[] = {type, promise, Undefined(isolate)}; | | 623 | + if (env->promise_reject_callback() | | 624 | + ->Call(context, Undefined(isolate), arraysize(args), args) | | 625 | + .IsEmpty()) { | | 626 | + return; | | 627 | + } | 612 | 628 | Local<Value> exception = promise->Result(); | 613 | 629 | Local<v8::Message> message = | 614 | 630 | 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!'); |
|