2011-09-21 173 views
12

我有一个PhantomJS脚本加载本地HTML文件,注入一些JavaScript文件,然后在页面上下文中执行一些JavaScript。运行的javascript会生成一个异常,但我只能从控制台获取输出,这似乎不能区分错误和正常日志,并且没有文件,行号或堆栈跟踪。如何捕获由PhantomJS获取的页面中生成的JavaScript错误?

我需要的是一种方法来捕获或以其他方式区分这些错误。我已经尝试:

  • 结束语在一个try-catch
    • 结果我PhantomJS脚本:没有什么是远远甩在了足以通过该
  • 被抓定义window.onerror功能
    • 结果:没有任何反应。 WebKit的不窗口

我宁愿能够检索错误对象本身,这样我可以检索堆栈跟踪上实施onerror事件。

+0

我想你的意思是定义一个'window.onerror'函数,对吧? –

+0

是的,固定的。谢谢! –

回答

8

我认为window.onerror在WebKit中无法正常工作(https://bugs.webkit.org/show_bug.cgi?id=8519)。不知道这是否已经修复,如果是这样,如果QT WebKit版本已经是最新的。

但是,您应该能够捕获代码中抛出的异常。如果您使用类似webPage.evaluate(...)的代码来运行代码,则无法将完整的调用包装在try/catch块中,因为脚本是在不同的上下文中评估的,并且这些错误不会出现在主执行上下文中。相反,您需要捕获页面执行上下文中的错误。不幸的是,没有办法访问在主要上下文中定义的任何函数,因此我们必须明确地编写代码周围的包装代码来执行。

以下是PhantomJS源中包含的phantomwebintro.js文件的修改示例。它加载一个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 
       // ... 
      } 

      ... 

     }); 
    } 
}); 

... 
+0

这将是一个很好的解决方案,但我试图在PhantomJS中运行的代码是异步的。不过,我相信最新版本的PhantomJS以及最新版本的QtWebKit通过允许window.onerror来解决了这个问题。 –

2

解决方案? 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; 
     };