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:
|
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
When trying to run the following code:
I encountered this error:
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
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 withconsole.error(err);I discovered that the original error is caused by thecloudflaredbinary 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:
Thank you for the library. 😊
Related issue: #30