denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
97.82k stars 5.39k forks source link

[node-compat] Getting `BadResource: Bad resource ID` on accessing console or process.stdout #19255

Closed brc-dd closed 8 months ago

brc-dd commented 1 year ago

Hey folks, getting this error when trying to make vitepress work with Deno.

error: Uncaught (in promise) BadResource: Bad resource ID
    at Object.isatty (ext:runtime/40_tty.js:19:7)
    at Writable.get [as isTTY] (ext:deno_node/_process/streams.mjs:57:31)
    at createLogger (file:///Users/divyansh/foo/node_modules/.deno/vitepress@1.0.0-beta.1/node_modules/vite/dist/node/chunks/dep-4d3eff22.js:12736:63)
    at file:///Users/divyansh/foo/node_modules/.deno/vitepress@1.0.0-beta.1/node_modules/vitepress/dist/node/cli.js:397:5
    at Object.runMicrotasks (ext:core/01_core.js:836:30)
    at processTicksAndRejections (ext:deno_node/_next_tick.ts:51:14)
    at runNextTicks (ext:deno_node/_next_tick.ts:69:5)
    at eventLoopTick (ext:core/01_core.js:188:21)

Reproduction: https://github.com/brc-dd/vitepress-on-deno (run deno task dev)

Removing console logging things seems to prevent the issue. Not completely sure what the cause is.

image

Quick checking suggests that any console.log statements before the createServer call work fine, but after that invocation, they tend to fail. Likely is due to something that createServer is doing.

Version details:

deno 1.34.0 (release, aarch64-apple-darwin)
v8 11.5.150.1
typescript 5.0.4
bartlomieju commented 1 year ago

Hey @brc-dd did you manage to solve this issue on your end? If not I'll be happy to take a look and fix it on our end.

brc-dd commented 1 year ago

Ah, no the issue wasn't fixed. I probably need to update the description. My initial assumptions were wrong, but I'm doing some more debugging. Will reopen it.

bartlomieju commented 1 year ago

Something is closing rid 1 (which is stdout). I will dig deeper to find what causes that.

bartlomieju commented 1 year ago

I've got a tentative fix ready that makes vitepress work.

bartlomieju commented 1 year ago

@brc-dd this fix will be available in Deno v1.34.2 to be released next week.

brc-dd commented 1 year ago

Awesome. Thanks 🙏

brc-dd commented 1 year ago

Hey, this is preventing the build task from ending for some reason 👀 . Will try to investigate / open separate issue. The reproduction is same as the above repository link, just run deno task build.

If we explicitly add process.exit() in dist/node/cli.js after build, it works fine. But that was intentionally removed from our side as it was closing streams abruptly before they can end.

bartlomieju commented 1 year ago

@brc-dd did the same problem happen before this change?

brc-dd commented 1 year ago

@bartlomieju No, something changed between v1.34.0 and v1.34.2. Earlier if I removed the console.log related statements, then build was working fine.

Logs:


  vitepress v1.0.0-beta.2

✓ building client + server bundles...
✓ rendering pages...
build complete in 2.14s.
Deno.resources() {
  "0": "stdin",
  "1": "stdout",
  "2": "stderr",
  "4": "signal",
  "5": "signal",
  "6": "signal",
  "7": "signal",
  "8": "signal",
  "9": "signal",
  "10": "signal",
  "11": "signal",
  "12": "signal",
  "13": "signal",
  "14": "signal",
  "15": "signal",
  "16": "signal",
  "66": "childStdin",
  "67": "childStdout",
  "68": "child"
}
^C
error: Uncaught Error: Input/output error (os error 5)
    at async read (ext:deno_io/12_io.js:103:17)
bartlomieju commented 1 year ago

Thanks, I will take a look

brc-dd commented 1 year ago

It might be specific to macOS. I'll test it out once on Linux/Windows too.

It runs fine with CI=true though: https://github.com/brc-dd/vitepress-on-deno/actions/runs/5243601024

A difference I can see on CI is those signal resources are not open 👀

Edit: doesn't work on Ubuntu either.

bartlomieju commented 1 year ago

@brc-dd sorry for a slow response. I just tried reproducing it and with deno task build I get errors related to missing APIs on window:

deno task build
Warning Currently only basic package.json `scripts` are supported. Programs like `rimraf` or `cross-env` will not work correctly. This will be fixed in an upcoming release.
Task build deno run -A --unstable --node-modules-dir npm:vitepress build

  vitepress v1.0.0-beta.1

✓ building client + server bundles...
⠋ rendering pages...TypeError: window.matchMedia is not a function
    at useAppearance (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1603:28)
    at setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1597:58)
    at _sfc_main$U.setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1670:25)
    at callWithErrorHandling (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:18:18)
    at setupStatefulComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5822:25)
    at setupComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5809:36)
    at renderComponentVNode (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:354:15)
    at ssrRenderComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:86:10)
    at file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1681:15
    at renderComponentSubTree (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:423:9)
TypeError: window.matchMedia is not a function
    at useAppearance (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1603:28)
    at setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1597:58)
    at _sfc_main$U.setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1670:25)
    at callWithErrorHandling (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:18:18)
    at setupStatefulComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5822:25)
    at setupComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5809:36)
    at renderComponentVNode (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:354:15)
    at ssrRenderComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:86:10)
    at file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1822:24
    at renderFnWithContext (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:357:13)
TypeError: window.matchMedia is not a function
    at useAppearance (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1603:28)
    at setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1597:58)
    at _sfc_main$U.setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1670:25)
    at callWithErrorHandling (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:18:18)
    at setupStatefulComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5822:25)
    at setupComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5809:36)
    at renderComponentVNode (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:354:15)
    at ssrRenderComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:86:10)
    at file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1681:15
    at renderComponentSubTree (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:423:9)
TypeError: window.matchMedia is not a function
    at useAppearance (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1603:28)
    at setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1597:58)
    at _sfc_main$U.setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1670:25)
    at callWithErrorHandling (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:18:18)
    at setupStatefulComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5822:25)
    at setupComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5809:36)
    at renderComponentVNode (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:354:15)
    at ssrRenderComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:86:10)
    at file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1822:24
    at renderFnWithContext (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:357:13)
TypeError: window.matchMedia is not a function
    at useAppearance (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1603:28)
    at setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1597:58)
    at _sfc_main$U.setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1670:25)
    at callWithErrorHandling (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:18:18)
    at setupStatefulComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5822:25)
    at setupComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5809:36)
    at renderComponentVNode (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:354:15)
    at ssrRenderComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:86:10)
    at file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1681:15
    at renderComponentSubTree (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:423:9)
TypeError: window.matchMedia is not a function
    at useAppearance (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1603:28)
    at setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1597:58)
    at _sfc_main$U.setup (file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1670:25)
    at callWithErrorHandling (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:18:18)
    at setupStatefulComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5822:25)
    at setupComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5809:36)
    at renderComponentVNode (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:354:15)
    at ssrRenderComponent (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+server-renderer@3.3.4/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:86:10)
    at file:///Users/ib/dev/vitepress-on-deno/.vitepress/.temp/app.js:1822:24
    at renderFnWithContext (file:///Users/ib/dev/vitepress-on-deno/node_modules/.deno/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:357:13)
✓ rendering pages...
build complete in 2.33s.

That said. After the errors are raised the process doesn't finish until I press Enter key. Which I assume is the bug you pointed out?

brc-dd commented 1 year ago

You should bump vitepress version. That matchMedia thing was fixed by checking typeof document !== 'undefined' instead of checking window one.

After the errors are raised the process doesn't finish until I press Enter key. Which I assume is the bug you pointed out?

Yeah. I hadn't checked by pressing enter though 😅

bartlomieju commented 1 year ago

@brc-dd does your program explicitly set raw mode for terminal? It appears this problem is related to https://github.com/denoland/deno/issues/17933 but I haven't been able to spot where the raw mode is getting disabled (or maybe it's not disabled and should be handled automatically somehow?).

brc-dd commented 1 year ago

Yeah setRawMode is there. I will check once by disabling the shortcuts thing.

bartlomieju commented 1 year ago

Interesting, so it appears Node.js somehow disables this raw mode automatically in some cases. I will need to chase it down.

brc-dd commented 1 year ago

Explicitly disabling it after build doesn't seem to work for me. Doing so keeps it running even after pressing enter. And we probably cannot remove that at vitepress level as some other dependency is calling that.

The setRawMode call that we are making for handling shortcuts is in dev. That should not affect the build command.

bartlomieju commented 1 year ago

I think I just found a test case in Node that describes the behavior:

// test/pseudo-tty/test-set-raw-mode-reset-process-exit.js
'use strict';
require('../common');
const child_process = require('child_process');

// Tests that exiting through process.exit() resets the TTY mode.

child_process.spawnSync(process.execPath, [
  '-e', 'process.stdin.setRawMode(true); process.exit(0)',
], { stdio: 'inherit' });

const { stdout } = child_process.spawnSync('stty', {
  stdio: ['inherit', 'pipe', 'inherit'],
  encoding: 'utf8',
});

if (stdout.match(/-echo\b/)) {
  console.log(stdout);
}

Does vitepress explicitly call process.exit()?

EDIT: Actually it seems that raw mode should be reset even if existing cleanly without process.exit() (test/pseudo-tty/test-set-raw-mode-reset.js)

brc-dd commented 1 year ago

Does vitepress explicitly call process.exit()?

No. Directly calling process.exit works, but it terminates the process before streams can finish (if the user has something in build hooks).

bartlomieju commented 1 year ago

@littledivy I know how to fix the terminal mode problem now, but I believe the hang is not really related to this PR. Any chance you could debug what's going on here?

littledivy commented 1 year ago

Seems to work with canary on Ubuntu:

divy@divy:~/gh/brc-dd/vitepress-on-deno$ deno -V
deno 1.35.0+75d2c04
divy@divy:~/gh/brc-dd/vitepress-on-deno$ deno task dev
Warning Currently only basic package.json `scripts` are supported. Programs like `rimraf` or `cross-env` will not work correctly. This will be fixed in an upcoming release.
Task dev deno run -A --unstable --node-modules-dir npm:vitepress dev

  vitepress v1.0.0-beta.5

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h to show help
littledivy commented 1 year ago

It seems this has been fixed in 1.35.0. I can no longer reproduce the error on macOS and Ubuntu

brc-dd commented 1 year ago

@littledivy Hey, try out build task without CI=true. The original issue was fixed by #19256

Refer this comment: https://github.com/denoland/deno/issues/19255#issuecomment-1586069241

littledivy commented 1 year ago

Thanks! The problem seems to be with the ora spinner module.

Here is a smaller reproduction:

import ora from "npm:ora";

const spinner = ora();
spinner.start('rendering...');

console.log('hello world');

spinner.stopAndPersist({ text: 'done' });
$ deno run test.mjs
⠋ rendering...hello world
  done
# hangs...
littledivy commented 1 year ago

The event loop is stuck polling op_signal_poll.

Deno.metrics() output:

    op_signal_poll: [Object: null prototype] {
      opsDispatched: 13,
      opsDispatchedSync: 0,
      opsDispatchedAsync: 13,
      opsDispatchedAsyncUnref: 0,
      opsCompleted: 0,
      opsCompletedSync: 0,
      opsCompletedAsync: 0,
      opsCompletedAsyncUnref: 0,
      bytesSentControl: 0,
      bytesSentData: 0,
      bytesReceived: 0
    },

https://github.com/denoland/deno/blob/be9e73d340373350c10bd30ca4f130b753287140/runtime/js/40_signals.js#L19-L23

littledivy commented 1 year ago

https://docs.rs/tokio/latest/tokio/signal/unix/struct.Signal.html#caveats

But, when a Signal instance is created to listen for this signal, the next SIGINT that arrives will be translated to a stream event, and the process will continue to execute.

bartlomieju commented 1 year ago

That looks like a bug with signal implementation - they should be "unrefed" meaning that they shouldn't prevent event loop from exiting.

brc-dd commented 1 year ago

Disabled stdin-discarder at vitepress to unblock. Feel free to close this if it can't be fixed at deno level (considering stdin-discarder is itself a bit hacky implementation).

Something at vitepress started causing hydration errors between beta-5 and beta-6 on deno (seems to work fine on node, beta-5 also works fine on deno). Will try to figure that and create a separate issue if that's something with deno.

bartlomieju commented 1 year ago

Disabled stdin-discarder at vitepress to unblock. Feel free to close this if it can't be fixed at deno level (considering stdin-discarder is itself a bit hacky implementation).

Thanks for the heads up @brc-dd. We are still trying to debug the problem with signals. Let's keep this issue open.

Something at vitepress started causing hydration errors between beta-5 and beta-6 on deno (seems to work fine on node, beta-5 also works fine on deno). Will try to figure that and create a separate issue if that's something with deno.

🙏 thanks, I'd appreciate a separate issue. A reproduction would be enough for us to figure out the problem.

bartlomieju commented 8 months ago

@littledivy just gave demo of using vitepress in Deno without encountering any errors. Can we close this issue now?

satyarohith commented 8 months ago

The initial reproduction repo is working without issues on latest deno.