-
Notifications
You must be signed in to change notification settings - Fork 6
Description
When trying to run the following code:
const { Tunnel } = await import('cloudflared')
const tunnel = Tunnel.quick('http://localhost:8000')
const url = await new Promise<string>(resolve => tunnel.on('url', resolve))I encountered this error:
RangeError: Maximum call stack size exceeded
at Tunnel.emit (node:events:465:44)
at Tunnel.emit (.../node_modules/cloudflared/lib/tunnel.js:112:18)
at Tunnel.<anonymous> (.../node_modules/cloudflared/lib/tunnel.js:78:12)
at Tunnel.emit (node:events:530:35)
at Tunnel.emit (.../node_modules/cloudflared/lib/tunnel.js:112:18)
at Tunnel.<anonymous> (.../node_modules/cloudflared/lib/tunnel.js:78:12)
at Tunnel.emit (node:events:530:35)
at Tunnel.emit (.../node_modules/cloudflared/lib/tunnel.js:112:18)
at Tunnel.<anonymous> (.../node_modules/cloudflared/lib/tunnel.js:78:12)
at Tunnel.emit (node:events:530:35)After some investigation, I found that this error originates from this block of code:
node-cloudflared/src/tunnel.ts
Lines 75 to 88 in 0b895ea
| private setupEventHandlers() { | |
| // cloudflared outputs to stderr, but I think its better to listen to stdout too | |
| this.on("stdout", (output) => { | |
| this.processOutput(output); | |
| }).on("error", (err) => { | |
| this.emit("error", err); | |
| }); | |
| this.on("stderr", (output) => { | |
| this.processOutput(output); | |
| }).on("error", (err) => { | |
| this.emit("error", err); | |
| }); | |
| } |
Specifically, the issue arises because inside .on('error'), it calls .emit("error", err) which causes an infinite loop by repeatedly listening to and emitting the same event.
After removing this.emit("error", err); and replacing it with console.error(err); I discovered that the original error is caused by the cloudflared binary not being found:
Error: spawn .../node_modules/cloudflared/bin/cloudflared ENOENT
at Process.ChildProcess._handle.onexit (node:internal/child_process:285:19)
at onErrorNT (node:internal/child_process:483:16)
at processTicksAndRejections (node:internal/process/task_queues:90:21) {
errno: -2,
code: 'ENOENT',
syscall: 'spawn .../node_modules/cloudflared/bin/cloudflared',
path: '.../node_modules/cloudflared/bin/cloudflared',
spawnargs: [ 'tunnel', '--url', 'http://localhost:8000' ]
}To avoid confusion, I suggest updating the documentation and the example script to include the use of install.
In my specific case, this is the final code without the error:
const fs = await import('fs')
const { Tunnel, bin, install } = await import('cloudflared')
if (!fs.existsSync(bin)) {
// install cloudflared binary
await install(bin)
}
const tunnel = Tunnel.quick('http://localhost:8000')
const url = await new Promise<string>(resolve => tunnel.on('url', resolve))Thank you for the library. 😊
Related issue: #30