Javascript try-catch 语义(nodejs repl 中的调用堆栈)

标签 javascript node.js try-catch read-eval-print-loop

我对 javascript 有点陌生,但我想尝试了解堆栈跟踪在 nodejs 中的工作原理。有点懒得看源码,直接查阅了语言引用https://www.ecma-international.org/ecma-262/10.0/index.html#sec-runtime-semantics-catchclauseevaluation并试图看看有什么用。所以,这就是谜团:在 repl 中,我在 catch 和 throw 时得到了一些奇怪的结果。

当我运行时:

try { throw Error('foo'); } catch (e) { throw e; }

我得到的输出是:

Error: foo

但是当我运行时:

try { throw Error('foo'); } catch (e) { console.log(e); throw e; }

我得到的输出是:

Error: foo
at repl:1:13
at ContextifyScript.Script.runInThisContext (vm.js:50:33)
at REPLServer.defaultEval (repl.js:240:29)
at bound (domain.js:301:14)
at REPLServer.runBound [as eval] (domain.js:314:12)
at REPLServer.onLine (repl.js:468:10)
at emitOne (events.js:121:20)
at REPLServer.emit (events.js:211:7)
at REPLServer.Interface._onLine (readline.js:282:10)
at REPLServer.Interface._line (readline.js:631:8)
Error: foo
at repl:1:13
at ContextifyScript.Script.runInThisContext (vm.js:50:33)
at REPLServer.defaultEval (repl.js:240:29)
at bound (domain.js:301:14)
at REPLServer.runBound [as eval] (domain.js:314:12)
at REPLServer.onLine (repl.js:468:10)
at emitOne (events.js:121:20)
at REPLServer.emit (events.js:211:7)
at REPLServer.Interface._onLine (readline.js:282:10)
at REPLServer.Interface._line (readline.js:631:8)

似乎调用 console.log(e) 会导致错误对象跟踪执行上下文堆栈(我希望我正确使用了这个术语),但是如果它在没有 context.log(e) 的情况下传递给 repl,它只知道它的错误消息。

我已经尝试过对此进行不同的排列,并在不同的词法上下文(函数和另一个 try-catch block )中嵌套,它们似乎都给出了这种“有趣”的行为。此外,当将这些作为脚本执行时,我总是会收到预期的错误消息和堆栈跟踪,因此我相信 repl 的实现在这里有问题。然而,在深入研究源代码之前,我想询问一些专家,看看这种行为是否有充分的理由,或者这是否只是我想出的一个愚蠢的极端案例。

最佳答案

好吧,我不知道回答我自己的问题是否符合犹太洁食标准,但我深入研究了 nodejs 源代码并发现了交易内容。我追踪到 repl.js: line 404。这里调用了 script.runInThisContext。此时,throw new Error() 行“转义”了 repl 并最终在下面几行中被捕获。在这里,检查了 process.domain,它显然在 repl 中成功,但在脚本上下文中却没有。然后这会发出一个域错误,但作用不大。如果您转到 self._domain.on('error',...,您会看到所有堆栈跟踪内容都在这里处理。

我实际上在 process.domain.emit('error',... 调用,然后它为我打印出一个很好的堆栈跟踪,所以我会写信给 nodejs 的人,看看他们是否想修复它。可能有一个很好的理由不这样做,我没有仔细研究它。

此时我想起了阅后即焚中的一个场景。如果你有一种干巴巴的幽默感,请观看:https://www.youtube.com/watch?v=46h7oP9eiBk

关于Javascript try-catch 语义(nodejs repl 中的调用堆栈),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58696013/

相关文章:

javascript - 如何使用 base-64 源创建 Image 对象?

javascript - CRM 2011 调用 getAttribute 失败

ruby - 终端 curl : (7) Failed to connect to localhost port 3000: Connection refused

java - 从 catch 中以及从 finally block 中抛出异常

javascript - 将事件附加到父代码中的 iframe 元素

javascript - NodeJS/Express 中的 "module.exports"和 "exports.methods"是什么意思?

javascript - Node.js - Express.js JWT 总是在浏览器响应中返回一个无效的 token 错误

javascript - 使用 $q 时, Angular promise 中的 catch 和 finally 函数不起作用,但标准 Promise 确实有效 - 我缺少什么?

java - java同一个类中多个方法中try catch的常用代码

javascript - Node js 什么时候应该使用异步机制