如何捕获 PhantomJS 获取的页面中生成的 JavaScript 错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7502899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I capture JavaScript errors generated in a page fetched by PhantomJS?
提问by James van Dyke
I have a PhantomJS script that loads a local HTML file, injects some javascript files, then executes some javascript in the context of the page. The javascript that runs generates an exception, but I only get output from the console, which doesn't seem to distinguish between an error and a normal log and doesn't have file, line numbers or a stacktrace.
我有一个 PhantomJS 脚本,它加载一个本地 HTML 文件,注入一些 javascript 文件,然后在页面的上下文中执行一些 javascript。运行的 javascript 生成异常,但我只从控制台获得输出,它似乎没有区分错误和正常日志,也没有文件、行号或堆栈跟踪。
What I need is a way to capture or otherwise distinguish these errors. I have already tried:
我需要的是一种捕获或以其他方式区分这些错误的方法。我已经尝试过:
- Wrapping my PhantomJS script in a try-catch
- Result: nothing is thrown far enough to be caught by this
- Define a
window.onerror
function- Result: nothing happens. WebKit does not implement an onerror event on the window
- 在 try-catch 中包装我的 PhantomJS 脚本
- 结果:没有任何东西被抛出到足以被这个捕获
- 定义一个
window.onerror
函数- 结果:什么也没有发生。WebKit 没有在窗口上实现 onerror 事件
I would prefer to be able to retrieve the error object itself so that I can retrieve the stacktrace.
我希望能够检索错误对象本身,以便我可以检索堆栈跟踪。
采纳答案by Julian D.
I think there were issues with window.onerror
not properly working in WebKit (https://bugs.webkit.org/show_bug.cgi?id=8519). Don't know if this has been fixed at all, and if so, if the QT WebKit version is already up-to-date.
我认为window.onerror
在 WebKit (https://bugs.webkit.org/show_bug.cgi?id=8519) 中无法正常工作存在问题。不知道这是否已完全修复,如果已修复,QT WebKit 版本是否已经是最新的。
However, you should be able to catch the exceptions thrown in your code. If you are using something like webPage.evaluate(...)
to run your code, you cannot wrap the complete call in a try/catch block, since the script is evaluated in a different context and the errors will not appear in the main execution context. Insteadyou will need to catch the errors in page execution context. Unfortunately, there is no way of accessing any functions defined in the main context, we therefore have to explicitly write the wrapping code around your code to be executed.
但是,您应该能够捕获代码中抛出的异常。如果您使用类似的东西webPage.evaluate(...)
来运行代码,则不能将完整的调用包装在 try/catch 块中,因为脚本是在不同的上下文中评估的,并且错误不会出现在主执行上下文中。相反,您需要在页面执行上下文中捕获错误。不幸的是,无法访问主上下文中定义的任何函数,因此我们必须明确地编写要执行的代码周围的包装代码。
The following is a modified example of the phantomwebintro.js
file as included in the PhantomJS source. It loads an HTML page, inserts a script and then runs some code in the page context (here with a line throwing a type error). This code is wrapped with a try/catch block and will return the wrapped result or error object to the main context.
以下是phantomwebintro.js
包含在 PhantomJS 源代码中的文件的修改示例。它加载一个 HTML 页面,插入一个脚本,然后在页面上下文中运行一些代码(这里有一行抛出类型错误)。此代码用 try/catch 块包装,并将包装的结果或错误对象返回到主上下文。
...
// Load an HTML page:
page.open("http://www.phantomjs.org", function(status) {
if (status == "success") {
// Inject some scripts:
page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
// Run your own code in the loaded page context:
var resultWrapper = page.evaluate(function() {
var wrapper = {};
try {
// Your code goes here
// ...
var x = undefined.x; // force an error
// store your return values in the wrapper
wrapper.result = 42;
} catch(error) {
wrapper.error = error;
}
return wrapper;
});
// Handle the result and possible errors:
if (resultWrapper.error) {
var error = resultWrapper.error;
console.log("An error occurred: " + error.message);
// continue handling the error
// ...
} else {
var result = resultWrapper.result;
// continue using the returned result
// ...
}
...
});
}
});
...
回答by Alexis Canyon
The solution? return true
!
解决方案?return true
!
// Error tracking
page.onError = function(msg, trace) {
console.log('= onError()');
var msgStack = [' ERROR: ' + msg];
if (trace) {
msgStack.push(' TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : ''));
});
}
console.log(msgStack.join('\n'));
// Consider error fully handled
return true;
};