2011-10-04 17 views
7

Tôi có một công cụ, tương tự như cách để JSFiddle, cho phép tôi tự động nhập vào javascript và chạy nó trên một trang. Mã có thể là nhiều dòng và thường sẽ là.mã tải động và nhận số dòng lỗi phân tích cú pháp

Thật không may nếu có một ngoại lệ trong mã tôi nhập vào, tôi không thể nhận được số dòng của ngoại lệ nếu tôi sử dụng eval() để chạy mã.

Tôi tìm thấy một giải pháp một phần, đó là thay vì sử dụng

try{ 
eval(code); 
} 
catch(e) { 
processException(e); 
} 

để thay làm một cái gì đó như thế này:

var s = document.createElement('script'); 
s.appendChild(document.createTextNode(
    "try{\n" + 
    code + 
    "}catch(e){processException(e)}")); 
document.body.appendChild(s); 

Bây giờ, nếu mã ném một ngoại lệ, và tôi nhìn vào stack trace (trong hàm processException() của tôi) tôi có thể nhận được một số dòng của ngoại lệ (trong firefox và chrome, anyway).

Đó là tất cả tốt và tốt nếu nó thực sự là một ngoại lệ thời gian chạy, chẳng hạn như một biến không được xác định. Vấn đề là nếu có một lỗi phân tích cú pháp/lỗi cú pháp, chẳng hạn như parens không khớp hoặc tương tự. Tôi không có gì cả.

Có cách giải quyết nào khác cho điều này, hoạt động trên firefox và chrome, ở mức tối thiểu? Đánh giá trong eval trong thẻ script trong đối tượng Function? Tôi đang cố gắng tất cả mọi thứ và không tìm thấy bất cứ điều gì hoạt động.

Trả lời

2

Cuối cùng tôi đã tìm được giải pháp hợp lý.

Trước tiên, tôi đặt window.onerror thành một số chức năng. Điều này không nhận được một dấu vết ngăn xếp đầy đủ, nhưng sẽ nhận được một tập tin và số dòng.

Sau đó, tôi làm điều này:

var s = document.createElement('script'); 
s.appendChild(document.createTextNode(
    "var someUniqueGlobalName = function() {\n" + 
    code + 
    "\n};"; 
document.body.appendChild(s); 

Lưu ý rằng điều này không thực sự chạy mã của tôi, vì nó chỉ đơn giản là tạo một hàm (trong phạm vi toàn cầu, với tên 'someUniqueGlobalName' - trong đó tất nhiên Tôi thực sự nghĩ ra một cái tên khác mỗi khi tôi làm điều này).

Nếu có lỗi cú pháp, nó sẽ bị bắt trong hàm window.onerror và tôi có thể nhận được loại lỗi và số dòng (dĩ nhiên tôi sẽ phải trừ một số từ, vì tôi đã thêm một dòng lúc bắt đầu).

Bây giờ, tôi chưa đặt window.onerror.

Cuối cùng, tôi chạy mã bằng cách gọi một sốUniqueGlobalName() trong khối try/catch. Ở đây tôi có thể nhận được một dấu vết stack đầy đủ với số dòng nếu có một lỗi thời gian chạy.

+0

Đây là một nguyên tắc thực sự hữu ích. Cảm ơn. – SystemParadox

1

Bạn có thể mang nó một bước xa hơn và tích hợp JSLint: https://github.com/douglascrockford/JSLint

Nó khá đơn giản .. đây là một thử nghiệm nhanh ...

Download: https://raw.github.com/douglascrockford/JSLint/master/jslint.js

jshint_test.html:

<script type="text/javascript" src="jslint.js"></script> 
<script> 

var result = JSLINT("var some = true;\nif (some) {"); 

if (result) 
{ 
    alert('Looking good'); 
} 
else 
{ 
    var error_message = ''; 
    for (i in JSLINT.errors) 
    { 
    var error = JSLINT.errors[i]; 
    error_message += error.reason + ' on line: ' + error.line + ' character: ' + error.character + "\n"; 
    } 
    alert(error_message); 
} 
</script> 

Kiểm tra tài liệu. Đối số thứ hai là JSLINT là một đối tượng tùy chọn .. có TẤN tùy chọn.

+0

ý tưởng sáng tạo nhưng không phải những gì tôi đang tìm kiếm. – rob

+1

Tò mò .. bạn đang tìm kiếm gì? Điều này cung cấp cho bạn các lỗi phân tích cú pháp và cú pháp như bạn đã yêu cầu ban đầu. – Jake

+0

Tôi sau khi chính xác, không phải ý kiến ​​của Crockford về những gì JS sẽ như thế nào. Ngoài ra nó cồng kềnh cho những gì tôi đang làm, vì vậy sẽ thích trình duyệt được xây dựng trong kiểm tra cú pháp – rob

Các vấn đề liên quan