TypeStrong/ts-node

UnhandledPromiseRejection: ts-node-esm does not display type checking results

jahirvidrio opened this issue · 8 comments

Search Terms

esm, node 20, UnhandledPromiseRejection

Expected Behavior

I expect to see the type checking errors displayed in the console when using ts-node with esm support, providing information about what went wrong during TypeScript compilation.

Actual Behavior

The console output from ts-node-esm does not include information about type checking errors, making it challenging to identify and resolve issues during development. Additionally, Node.js reports the following error:

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "[object Object]".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

I tried using it with ts-node-esm and also with the --loader ts-node/esm option.

If I remove ESM support, everything works correctly, and I can see the type checking report from tsc.

Steps to reproduce the problem

const str: number = 'hello world';

console.log(str);

Minimal reproduction

Just run ts-node with esm support

$ NODE_OPTIONS="--no-warnings=ExperimentalWarning --experimental-loader=ts-node/esm" ts-node main.ts

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "[object Object]".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

Specifications

  • ts-node version: 10.9.1
  • node version: 20.9.0
  • TypeScript version: 5.2.2
  • tsconfig.json
{
    "compilerOptions": {
        "target": "es2022",
        "module": "es2022"
    },
    "ts-node": {
        "esm": true,
        "experimentalSpecifierResolution": "node"
    }
}
  • package.json:
{
    "type": "module",
    "scripts": {
        "start": "NODE_OPTIONS=\"--no-warnings=ExperimentalWarning --experimental-loader=ts-node/esm\" ts-node main.ts"
    },
    "devDependencies": {
        "ts-node": "^10.9.1",
        "tslib": "^2.6.2",
        "typescript": "^5.2.2"
    }
}
  • Operating system and version: Linux Debian in docker dev container node:20.9.0-bookworm

I feel my issue fits into this.

ts-node v10.9.1

When I have simple code like

import http from 'http';

And I run it via

node --loader ts-node/esm bin/test.ts

in Node 20. I get the output

node:internal/process/esm_loader:40
      internalBinding('errors').triggerUncaughtException(
                                ^
[Object: null prototype] {
  [Symbol(nodejs.util.inspect.custom)]: [Function: [nodejs.util.inspect.custom]]
}

Node.js v20.9.0

When I execute it in Node 18.18.2 I get the output

/[...]/node_modules/ts-node/src/index.ts:859
    return new TSError(diagnosticText, diagnosticCodes, diagnostics);
           ^
TSError: ⨯ Unable to compile TypeScript:
bin/test.ts:1:1 - error TS6133: 'http' is declared but its value is never read.

1 import http from 'http';
  ~~~~~~~~~~~~~~~~~~~~~~~~

    at createTSError
    [...]

This is of corse an academic example but also applies for way more complex projects

I tried multiple ways of executing node with ts-node all yield the same result.

@TarSzator Your issue is not actually an error; it's a configuration in your tsconfig.json file that instructs the compiler to throw an error when a variable is not used. Simply modify the compilerOptions.noUnusedLocals and compilerOptions.noUnusedParameters properties to false.

@jahirvidrio The issue is not that I see an error. The issue is that I not see it when I use Node v20.

Meaning that I do not see a proper error message when I use Node v20

I'm seeing the same issue as @TarSzator. It seems the problem now also exists in node-18.19.0:

$ node --version
v18.18.2
$ NODE_OPTIONS="--no-warnings=ExperimentalWarning --experimental-loader=ts-node/esm" npx ts-node main.ts
/node_modules/ts-node/src/index.ts:859
    return new TSError(diagnosticText, diagnosticCodes, diagnostics);
           ^
TSError: ⨯ Unable to compile TypeScript:
main.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'.
$ node --version
v18.19.0
$ NODE_OPTIONS="--no-warnings=ExperimentalWarning --experimental-loader=ts-node/esm" npx ts-node main.ts
[Object: null prototype] {
  [Symbol(nodejs.util.inspect.custom)]: [Function: [nodejs.util.inspect.custom]]
}
$ node --version
v20.10.0
$ NODE_OPTIONS="--no-warnings=ExperimentalWarning --experimental-loader=ts-node/esm" npx ts-node main.ts
[Object: null prototype] {
  [Symbol(nodejs.util.inspect.custom)]: [Function: [nodejs.util.inspect.custom]]
}

Hello TypeScript team!

I appear to also be experiencing this with my loader command:

api-1  | > node --no-warnings --watch --loader ts-node/esm index.ts
api-1  | 
api-1  | 
api-1  | node:internal/process/esm_loader:40
api-1  |       internalBinding('errors').triggerUncaughtException(
api-1  |                                 ^
api-1  | [Object: null prototype] {
api-1  |   [Symbol(nodejs.util.inspect.custom)]: [Function: [nodejs.util.inspect.custom]]
api-1  | }
api-1  | 
api-1  | Node.js v18.19.0
api-1  | Failed running 'index.ts'

Any help would be appreciated!

Apologies, team I misinterpreted @cj-christoph-gysin's answer as a confirmation that (all) node 18 minor versions worked and that it was just node 20 -- but didn't know I could simply downgrade from my existing 18.19.0 Docker image to the 18.18.2 image build... Which I can now happily confirm a second time - works!

I'm not terribly familiar with node/ts/es6 internals but does that mean it's a problem with the ts-node loader, or could it still be a weird minor version node runtime change?

Still an issue...

Bump.
By the way. Its helped for me, but now if any errors execution of the script does not stops:
compilerOptions.ts-node.logError=true
compilerOptions.ts-node.pretty=true