首先,我知道捕获未捕获的错误的一种方法是使用<?php
if(isset($_POST['MEASURE']))
{
shell_exec("sudo python /var/www/html/lab/mkdir.py");
}
?>
。
我想知道如何为错误传递更多详细信息或更多上下文。我希望能够获得使用的变量。我不是要从错误中恢复,而是要在关闭进程之前获取发生错误时我所处环境的更多详细信息。是的,堆栈跟踪很好,但是我想知道如何复制错误。
例如,我具有以下功能:
<form method="post" >
<input type="submit" value="Start Measuring" name="MEASURE" class="search">
</form>
在process.on('uncaughtException', err, function() {});
上,我希望能够访问function doTheBatman(var1) {
var var2 = 'whatever';
// this causes an uncaught exception later in the code
}
和process.on
。
var1
答案 0 :(得分:1)
Express路由处理程序中的同步异常将被Express本身捕获,并且该异常将从默认的Express错误处理程序中传递出去,您可以在其中自己捕获它,并将异常上下文传递给该默认的Express错误处理程序。
您会看到this code inside of Express在其中调用了路由处理程序:
Layer.prototype.handle_request = function handle(req, res, next) {
var fn = this.handle;
if (fn.length > 3) {
// not a standard request handler
return next();
}
try {
fn(req, res, next);
} catch (err) {
next(err);
}
};
对next(err)
的调用会将异常对象传递给默认的Express错误处理程序(you can install a handler for)。
如果您的代码在异步回调内部引发异常,则执行起来会更加复杂。如果您使用的是常规的异步回调(而不是诺言),那么我所知道的要在有意义的地方抓住它们的唯一方法是在每个异步回调中放入try/catch
,以便捕获本地堆栈信息。
如果您在最低级别使用承诺,并且仅对逻辑和异步代码流进行编程,则使用承诺功能,那么承诺处理程序中的异常将自动变成拒绝的承诺和某些承诺库(例如可以配置Bluebird库)为您提供错误发生位置的完整堆栈跟踪)。承诺之所以具有此优势,是因为每个承诺.then()
或.catch()
处理程序都会自动包装在try/catch
处理程序中,而这些承诺处理程序将变成承诺拒绝,并沿链条传播到第一个.catch()
他们找到的处理程序。
对于您刚刚添加到问题中的非Express示例,您只需在本地邻居中放置try / catch即可捕获本地同步异常:
function doTheBatman(var1) {
try {
var var2 = 'whatever';
// this causes an uncaught exception later in the code
} catch(e) {
console.log(e);
}
}
您甚至可以在catch
处理程序中设置调试器断点,然后在命中该作用域时检查该变量。我不知道有什么方法可以在uncaughtException
处理程序发生异常时检查局部变量。 err.stack
应该给您堆栈跟踪,而不是变量值。
答案 1 :(得分:1)
Express / frameworks可能会提供更优雅/更强大的解决方案,但是如果您确实满足您的问题的要求...为什么不仅仅捕获函数范围之外的变量?这通常很讨厌,不被认为是最佳实践,但是如果您知道某个功能可能经常导致故障,那么可能需要快速而肮脏的解决方案。您以后可以随时对其进行优化,但是希望这可以演示该方法...
var transactionVars = {};
function clearTransaction() {
transactionVars = {};
}
function doTheBatman(var1) {
transactionVars['var2'] = 'whatever';
// [...] bunch of stuff, possibly blowing up...
clearTransaction(); // we made it this far? cool, reset...
}
process.on('uncaughtException', function(err) {
console.log(transactionVars['var2']); // whatever
});
此外,如果您想真正变脏(如果这两个函数位于两个文件中),则可以始终在global对象上添加transactionVars
。
这本质上是一个穷人事件发射器模式,一旦您掌握了它的工作原理,我强烈建议将其重构为...