| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 62bb2e7 commit 35ef990
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2566,6 +2566,8 @@ cases: | |||
| 2566 | 2566 | and generally can only happen during development of Node.js itself. | |
| 2567 | 2567 | * `12` **Invalid Debug Argument**: The `--inspect` and/or `--inspect-brk` | |
| 2568 | 2568 | options were set, but the port number chosen was invalid or unavailable. | |
| 2569 | + * `13` **Unfinished Top-Level Await**: `await` was used outside of a function | ||
| 2570 | + in the top-level code, but the passed `Promise` never resolved. | ||
| 2569 | 2571 | * `>128` **Signal Exits**: If Node.js receives a fatal signal such as | |
| 2570 | 2572 | `SIGKILL` or `SIGHUP`, then its exit code will be `128` plus the | |
| 2571 | 2573 | value of the signal code. This is a standard POSIX practice, since | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -40,11 +40,23 @@ function shouldUseESMLoader(mainPath) { | |||
| 40 | 40 | function runMainESM(mainPath) { | |
| 41 | 41 | const esmLoader = require('internal/process/esm_loader'); | |
| 42 | 42 | const { pathToFileURL } = require('internal/url'); | |
| 43 | - esmLoader.loadESM((ESMLoader) => { | ||
| 43 | + handleMainPromise(esmLoader.loadESM((ESMLoader) => { | ||
| 44 | 44 | const main = path.isAbsolute(mainPath) ? | |
| 45 | 45 | pathToFileURL(mainPath).href : mainPath; | |
| 46 | 46 | return ESMLoader.import(main); | |
| 47 | - }); | ||
| 47 | + })); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + function handleMainPromise(promise) { | ||
| 51 | + // Handle a Promise from running code that potentially does Top-Level Await. | ||
| 52 | + // In that case, it makes sense to set the exit code to a specific non-zero | ||
| 53 | + // value if the main code never finishes running. | ||
| 54 | + function handler() { | ||
| 55 | + if (process.exitCode === undefined) | ||
| 56 | + process.exitCode = 13; | ||
| 57 | + } | ||
| 58 | + process.on('exit', handler); | ||
| 59 | + return promise.finally(() => process.off('exit', handler)); | ||
| 48 | 60 | } | |
| 49 | 61 | ||
| 50 | 62 | // For backwards compatibility, we have to run a bunch of | |
@@ -62,5 +74,6 @@ function executeUserEntryPoint(main = process.argv[1]) { | |||
| 62 | 74 | } | |
| 63 | 75 | ||
| 64 | 76 | module.exports = { | |
| 65 | - executeUserEntryPoint | ||
| 77 | + executeUserEntryPoint, | ||
| 78 | + handleMainPromise, | ||
| 66 | 79 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,7 +2,6 @@ | |||
| 2 | 2 | ||
| 3 | 3 | const { | |
| 4 | 4 | JSONStringify, | |
| 5 | - PromiseResolve, | ||
| 6 | 5 | } = primordials; | |
| 7 | 6 | ||
| 8 | 7 | const path = require('path'); | |
@@ -43,20 +42,15 @@ function evalModule(source, print) { | |||
| 43 | 42 | if (print) { | |
| 44 | 43 | throw new ERR_EVAL_ESM_CANNOT_PRINT(); | |
| 45 | 44 | } | |
| 46 | - const { log, error } = require('internal/console/global'); | ||
| 47 | - const { decorateErrorStack } = require('internal/util'); | ||
| 48 | - const asyncESM = require('internal/process/esm_loader'); | ||
| 49 | - PromiseResolve(asyncESM.ESMLoader).then(async (loader) => { | ||
| 45 | + const { log } = require('internal/console/global'); | ||
| 46 | + const { loadESM } = require('internal/process/esm_loader'); | ||
| 47 | + const { handleMainPromise } = require('internal/modules/run_main'); | ||
| 48 | + handleMainPromise(loadESM(async (loader) => { | ||
| 50 | 49 | const { result } = await loader.eval(source); | |
| 51 | 50 | if (print) { | |
| 52 | 51 | log(result); | |
| 53 | 52 | } | |
| 54 | - }) | ||
| 55 | - .catch((e) => { | ||
| 56 | - decorateErrorStack(e); | ||
| 57 | - error(e); | ||
| 58 | - process.exit(1); | ||
| 59 | - }); | ||
| 53 | + })); | ||
| 60 | 54 | } | |
| 61 | 55 | ||
| 62 | 56 | function evalScript(name, body, breakFirstLine, print) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,82 @@ | |||
| 1 | + import '../common/index.mjs'; | ||
| 2 | + import assert from 'assert'; | ||
| 3 | + import child_process from 'child_process'; | ||
| 4 | + import fixtures from '../common/fixtures.js'; | ||
| 5 | + | ||
| 6 | + { | ||
| 7 | + // Unresolved TLA promise, --eval | ||
| 8 | + const { status, stdout, stderr } = child_process.spawnSync( | ||
| 9 | + process.execPath, | ||
| 10 | + ['--input-type=module', '--eval', 'await new Promise(() => {})'], | ||
| 11 | + { encoding: 'utf8' }); | ||
| 12 | + assert.deepStrictEqual([status, stdout, stderr], [13, '', '']); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + { | ||
| 16 | + // Rejected TLA promise, --eval | ||
| 17 | + const { status, stdout, stderr } = child_process.spawnSync( | ||
| 18 | + process.execPath, | ||
| 19 | + ['--input-type=module', '-e', 'await Promise.reject(new Error("Xyz"))'], | ||
| 20 | + { encoding: 'utf8' }); | ||
| 21 | + assert.deepStrictEqual([status, stdout], [1, '']); | ||
| 22 | + assert.match(stderr, /Error: Xyz/); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + { | ||
| 26 | + // Unresolved TLA promise with explicit exit code, --eval | ||
| 27 | + const { status, stdout, stderr } = child_process.spawnSync( | ||
| 28 | + process.execPath, | ||
| 29 | + ['--input-type=module', '--eval', | ||
| 30 | + 'process.exitCode = 42;await new Promise(() => {})'], | ||
| 31 | + { encoding: 'utf8' }); | ||
| 32 | + assert.deepStrictEqual([status, stdout, stderr], [42, '', '']); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + { | ||
| 36 | + // Rejected TLA promise with explicit exit code, --eval | ||
| 37 | + const { status, stdout, stderr } = child_process.spawnSync( | ||
| 38 | + process.execPath, | ||
| 39 | + ['--input-type=module', '-e', | ||
| 40 | + 'process.exitCode = 42;await Promise.reject(new Error("Xyz"))'], | ||
| 41 | + { encoding: 'utf8' }); | ||
| 42 | + assert.deepStrictEqual([status, stdout], [1, '']); | ||
| 43 | + assert.match(stderr, /Error: Xyz/); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + { | ||
| 47 | + // Unresolved TLA promise, module file | ||
| 48 | + const { status, stdout, stderr } = child_process.spawnSync( | ||
| 49 | + process.execPath, | ||
| 50 | + [fixtures.path('es-modules/tla/unresolved.mjs')], | ||
| 51 | + { encoding: 'utf8' }); | ||
| 52 | + assert.deepStrictEqual([status, stdout, stderr], [13, '', '']); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + { | ||
| 56 | + // Rejected TLA promise, module file | ||
| 57 | + const { status, stdout, stderr } = child_process.spawnSync( | ||
| 58 | + process.execPath, | ||
| 59 | + [fixtures.path('es-modules/tla/rejected.mjs')], | ||
| 60 | + { encoding: 'utf8' }); | ||
| 61 | + assert.deepStrictEqual([status, stdout], [1, '']); | ||
| 62 | + assert.match(stderr, /Error: Xyz/); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + { | ||
| 66 | + // Unresolved TLA promise, module file | ||
| 67 | + const { status, stdout, stderr } = child_process.spawnSync( | ||
| 68 | + process.execPath, | ||
| 69 | + [fixtures.path('es-modules/tla/unresolved-withexitcode.mjs')], | ||
| 70 | + { encoding: 'utf8' }); | ||
| 71 | + assert.deepStrictEqual([status, stdout, stderr], [42, '', '']); | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + { | ||
| 75 | + // Rejected TLA promise, module file | ||
| 76 | + const { status, stdout, stderr } = child_process.spawnSync( | ||
| 77 | + process.execPath, | ||
| 78 | + [fixtures.path('es-modules/tla/rejected-withexitcode.mjs')], | ||
| 79 | + { encoding: 'utf8' }); | ||
| 80 | + assert.deepStrictEqual([status, stdout], [1, '']); | ||
| 81 | + assert.match(stderr, /Error: Xyz/); | ||
| 82 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + process.exitCode = 42; | ||
| 2 | + await Promise.reject(new Error('Xyz')); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + await Promise.reject(new Error('Xyz')); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + process.exitCode = 42; | ||
| 2 | + await new Promise(() => {}); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + await new Promise(() => {}); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments