2011-09-21 174 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; 
     };