2015-07-09 22 views
10

Tôi đang gặp khó khăn trong việc hiểu cách PhantomJS xử lý lỗi.Xử lý lỗi PhantomJS

Tôi có một máy chủ Apache được cài đặt cục bộ đang chạy (xampp) và khi tôi truy cập theo cách thủ công "http://localhost/" Tôi nhận được thông báo "Hoạt động!" trang.

Là một thử nghiệm, tôi đã viết một tập tin nhỏ (gọi là forceError.js) mà cố tình gây ra một ngoại lệ được kiểm soát:

var page = require('webpage').create(), 
    url = 'http://localhost/'; 

page.onError = function(msg, trace) { 
    console.log("page.onError"); 
    var msgStack = ['ERROR: ' + msg]; 
    if (trace && trace.length) { 
    msgStack.push('TRACE:'); 
    trace.forEach(function(t) { 
     msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : '')); 
    }); 
    } 
    console.error(msgStack.join('\n')); 
}; 

phantom.onError = function(msg, trace) { 
    console.log("phantom.onError"); 
    var msgStack = ['PHANTOM ERROR: ' + msg]; 
    if (trace && trace.length) { 
    msgStack.push('TRACE:'); 
    trace.forEach(function(t) { 
     msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : '')); 
    }); 
    } 
    console.error(msgStack.join('\n')); 
    phantom.exit(1); 
}; 

page.open(url, function (status) { 
    console.log("status: " + status); 

    // an undefined function 
    thisShouldForceAnError(); 
}); 

Khi tôi chạy sử dụng này:

phantomjs.exe forceError.js 

Trước tiên tôi nhận được " trạng thái: thành công "và sau đó quá trình chỉ bị treo. Tôi không thấy page.onError hoặc phantom.onError được gọi.

Có một số thuộc tính hoặc thứ gì đó tôi cần bật để xử lý lỗi chung không?

Tôi đang sử dụng Windows 7, PhantomJS phiên bản 2.0.0 và chạy trong vỏ "git bash" của tôi.

+1

Có thể tốt hơn là sự cố trên GitHub. Có vẻ như một lỗi trong PhantomJS 2. –

+0

@ArtjomB. Ý tưởng hay: https://github.com/lichunqiang/lichunqiang.github.io/issues/13 –

+0

@ArtjomB. cảm ơn: https://github.com/ariya/phantomjs/issues/13403 –

Trả lời

7

Được thử nghiệm trên hệ điều hành MacOS và trải nghiệm chính xác cùng một hành vi, thực sự hơi khó hiểu và rất có thể chỉ là lỗi. Điều kỳ lạ là, nếu bạn gọi một chức năng không xác định từ phạm vi tối đa nhất phantom.onError được gọi đúng .

Giải pháp thay thế bạn chỉ có thể quấn nội dung của cuộc gọi lại open với số try/catch. Hy vọng rằng nó sẽ làm công việc.

Chỉ cần làm rõ: page.onError được gọi nếu xảy ra lỗi trong khi thực thi mã của trang được yêu cầu - không phải chính tập lệnh ảo. Tôi đã dựa vào page.onError trong một thời gian và có vẻ như hoạt động khá ổn định. (Mặc dù một số lỗi chỉ xảy ra trong công cụ phantomjs, nhưng không phải trong thường xuyên trình duyệt.)


Trên thực tế: "phantom.onError" được in trên bàn điều khiển vô hạn như console.error không được hỗ trợ bởi phantomjs.

+0

Thử 'return true;' trên 'page.onError' –

6

Câu trả lời được chấp nhận rất hữu ích, nhưng tôi sẽ bổ sung nó bằng mẫu mã.

page.open("https://www.google.com/", function (status) { 
    try { 
     if (status !== "success") { 
      console.log("Unable to access network"); 
     } else { 
      //do some stuff with the DOM 
     }   
    } catch (ex) { 
     var fullMessage = "\nJAVASCRIPT EXCEPTION"; 
     fullMessage += "\nMESSAGE: " + ex.toString(); 
     for (var p in ex) { 
      fullMessage += "\n" + p.toUpperCase() + ": " + ex[p]; 
     } 
     console.log(fullMessage); 
    } 
}); 

Output sẽ trông giống như ảnh chụp màn hình này: Output

UPDATE: này dường như là một lỗi đặc biệt với page.open. Tôi nhận thấy rằng phantom.onError đang thu hút mọi thứ từ cuộc gọi lại, không phải trực tiếp trong số page.open. Đây là một cách giải quyết khác có thể xảy ra. Điều này ít nhất cho phép bạn có tất cả các mã xử lý lỗi trong một chỗ thay vì có một loạt các try/catches. LƯU Ý: Bạn vẫn cần page.onError cho những thứ bên trong page.evaluate.

page.open(genericSignInPageUrl, function (status) { 
    setTimeout(function() { //hack for page.open not hooking into phantom.onError 
     if (status !== "success") { 
      throw new Error("Unable to access network"); 
     } 
     //do some stuff 
    }, 0); 
}); 

Khi thực sự làm việc với trang, tôi đã bắt đầu sử dụng điều này để đảm bảo yếu tố tôi đang tìm kiếm ở đó.Vì mã của tôi đang gọi lại, các phương thức onError hoạt động tốt. Mã cho phương pháp waitFor là ở đây: https://github.com/ariya/phantomjs/blob/master/examples/waitfor.js

page.open(genericSignInPageUrl, function() { 
    waitFor(function() { 
     return page.evaluate(function() { 
      return document.getElementById("idOfElementToIndicatePageLoaded"); 
     }); 
    }, function() { 
     //do some stuff with the page 
    }); 
});