Tôi muốn bắt tất cả các lỗi chức năng không xác định ném. Có một cơ sở xử lý lỗi toàn cầu trong JavaScript? Ca sử dụng đang bắt các cuộc gọi chức năng từ flash không được xác định.
Tôi muốn bắt tất cả các lỗi chức năng không xác định ném. Có một cơ sở xử lý lỗi toàn cầu trong JavaScript? Ca sử dụng đang bắt các cuộc gọi chức năng từ flash không được xác định.
Câu trả lời:
Điều này có giúp bạn không:
<script type="text/javascript">
window.onerror = function() {
alert("Error caught");
};
xxx();
</script>
Tôi không chắc cách nó xử lý lỗi Flash mặc dù ...
Cập nhật: nó không hoạt động trong Opera, nhưng tôi đang hack Dragonfly ngay bây giờ để xem những gì nó nhận được. Gợi ý về việc hack Dragonfly xuất phát từ câu hỏi này:
Cửa sổ bắt chước. onerror trong Opera bằng cách sử dụng javascript
window.onerror = function() { alert(42) };
bây giờ mã trong câu trả lời: window.onerror = function() { alert("Error caught"); };
không overriden, tôi vẫn không chắc chắn ..
Chỉ định window.onerror
sự kiện cho một trình xử lý sự kiện như:
<script type="text/javascript">
window.onerror = function(msg, url, line, col, error) {
// Note that col & error are new to the HTML 5 spec and may not be
// supported in every browser. It worked for me in Chrome.
var extra = !col ? '' : '\ncolumn: ' + col;
extra += !error ? '' : '\nerror: ' + error;
// You can view the information in an alert to see things working like this:
alert("Error: " + msg + "\nurl: " + url + "\nline: " + line + extra);
// TODO: Report this error via ajax so you can keep track
// of what pages have JS issues
var suppressErrorAlert = true;
// If you return true, then error alerts (like in older versions of
// Internet Explorer) will be suppressed.
return suppressErrorAlert;
};
</script>
Như đã nhận xét trong mã, nếu giá trị trả về window.onerror
là true
thì trình duyệt sẽ chặn hiển thị hộp thoại cảnh báo.
Tóm lại, sự kiện được nêu ra khi 1.) có ngoại lệ chưa được xử lý hoặc 2.) xảy ra lỗi thời gian biên dịch.
ngoại lệ
- ném "vài tin nhắn"
- call_s Something_und xác định ();
- cross_origin_iframe.contentWindow.document;, một ngoại lệ bảo mật
Lỗi biên dịch
<script>{</script>
<script>for(;)</script>
<script>"oops</script>
setTimeout("{", 10);
, nó sẽ cố gắng biên dịch đối số đầu tiên dưới dạng tập lệnh
Ví dụ về mã onerror ở trên trong hành động sau khi thêm mã này vào trang thử nghiệm:
<script type="text/javascript">
call_something_undefined();
</script>
var error_data = {
url: document.location.href,
};
if(error != null) {
error_data['name'] = error.name; // e.g. ReferenceError
error_data['message'] = error.line;
error_data['stack'] = error.stack;
} else {
error_data['msg'] = msg;
error_data['filename'] = filename;
error_data['line'] = line;
error_data['col'] = col;
}
var xhr = new XMLHttpRequest();
xhr.open('POST', '/ajax/log_javascript_error');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status === 200) {
console.log('JS error logged');
} else if (xhr.status !== 200) {
console.error('Failed to log JS error.');
console.error(xhr);
console.error(xhr.status);
console.error(xhr.responseText);
}
};
xhr.send(JSON.stringify(error_data));
https://jsfiddle.net/nzfvm44d/
throw
được thực hiện thủ công. stackoverflow.com/questions/15036165/ cường
Nếu việc xử lý lỗi của bạn rất phức tạp và do đó có thể tự gây ra lỗi, sẽ rất hữu ích khi thêm cờ cho biết bạn đã ở trong "chế độ lỗi". Thích như vậy:
var appIsHandlingError = false;
window.onerror = function() {
if (!appIsHandlingError) {
appIsHandlingError = true;
handleError();
}
};
function handleError() {
// graceful error handling
// if successful: appIsHandlingError = false;
}
Nếu không, bạn có thể thấy mình trong một vòng lặp vô hạn.
handleError
phương pháp thử bắt xung quanh phương pháp.
Hãy thử Atatus cung cấp tính năng Theo dõi lỗi nâng cao và Giám sát người dùng thực cho các ứng dụng web hiện đại.
Hãy để tôi giải thích làm thế nào để có được stacktraces hoàn thành hợp lý trong tất cả các trình duyệt.
Chrome và Opera hiện đại hỗ trợ đầy đủ thông số dự thảo HTML 5 cho ErrorEvent và window.onerror
. Trong cả hai trình duyệt này, bạn có thể sử dụng window.onerror
hoặc liên kết đúng với sự kiện 'lỗi':
// Only Chrome & Opera pass the error object.
window.onerror = function (message, file, line, col, error) {
console.log(message, "from", error.stack);
// You can send data to your server
// sendError(data);
};
// Only Chrome & Opera have an error attribute on the event.
window.addEventListener("error", function (e) {
console.log(e.error.message, "from", e.error.stack);
// You can send data to your server
// sendError(data);
})
Thật không may, Firefox, Safari và IE vẫn còn và chúng tôi cũng phải hỗ trợ chúng. Vì stacktrace không có sẵn nên window.onerror
chúng tôi phải làm thêm một chút.
Nó chỉ ra rằng điều duy nhất chúng ta có thể làm để nhận stacktraces từ các lỗi là bọc tất cả các mã của chúng ta trong một try{ }catch(e){ }
khối và sau đó xem xét e.stack
. Chúng ta có thể làm cho quá trình dễ dàng hơn với một hàm gọi là hàm lấy hàm và trả về một hàm mới với khả năng xử lý lỗi tốt.
function wrap(func) {
// Ensure we only wrap the function once.
if (!func._wrapped) {
func._wrapped = function () {
try{
func.apply(this, arguments);
} catch(e) {
console.log(e.message, "from", e.stack);
// You can send data to your server
// sendError(data);
throw e;
}
}
}
return func._wrapped;
};
Những công việc này. Bất kỳ chức năng nào bạn bọc thủ công sẽ xử lý lỗi tốt, nhưng hóa ra chúng tôi thực sự có thể tự động làm điều đó cho bạn trong hầu hết các trường hợp.
Bằng cách thay đổi định nghĩa toàn cầu addEventListener
để nó tự động kết thúc cuộc gọi lại, chúng ta có thể tự động chèn try{ }catch(e){ }
xung quanh hầu hết mã. Điều này cho phép mã hiện có tiếp tục hoạt động, nhưng thêm theo dõi ngoại lệ chất lượng cao.
var addEventListener = window.EventTarget.prototype.addEventListener;
window.EventTarget.prototype.addEventListener = function (event, callback, bubble) {
addEventListener.call(this, event, wrap(callback), bubble);
}
Chúng tôi cũng cần đảm bảo rằng removeEventListener
tiếp tục làm việc. Tại thời điểm này, nó sẽ không vì đối số addEventListener
được thay đổi. Một lần nữa chúng ta chỉ cần sửa lỗi này trên prototype
đối tượng:
var removeEventListener = window.EventTarget.prototype.removeEventListener;
window.EventTarget.prototype.removeEventListener = function (event, callback, bubble) {
removeEventListener.call(this, event, callback._wrapped || callback, bubble);
}
Bạn có thể gửi dữ liệu lỗi bằng thẻ hình ảnh như sau
function sendError(data) {
var img = newImage(),
src = 'http://yourserver.com/jserror&data=' + encodeURIComponent(JSON.stringify(data));
img.crossOrigin = 'anonymous';
img.onload = function success() {
console.log('success', data);
};
img.onerror = img.onabort = function failure() {
console.error('failure', data);
};
img.src = src;
}
Tuyên bố miễn trừ trách nhiệm: Tôi là nhà phát triển web tại https://www.atatus.com/ .
http://yourserver.com
) để nhận và lưu trữ. Nếu bạn chọn atatus.com , bạn không cần phải làm gì cả. Chỉ cần bao gồm hai dòng script trong trang của bạn.
Dường như window.onerror
không cung cấp quyền truy cập vào tất cả các lỗi có thể. Cụ thể nó bỏ qua:
<img>
tải lỗi (phản hồi> = 400).<script>
tải lỗi (phản hồi> = 400).window.onerror
theo cách không xác định (jquery, angular, v.v.).Đây là sự khởi đầu của một tập lệnh bắt được nhiều lỗi này, do đó bạn có thể thêm gỡ lỗi mạnh mẽ hơn cho ứng dụng của mình trong quá trình phát triển.
(function(){
/**
* Capture error data for debugging in web console.
*/
var captures = [];
/**
* Wait until `window.onload`, so any external scripts
* you might load have a chance to set their own error handlers,
* which we don't want to override.
*/
window.addEventListener('load', onload);
/**
* Custom global function to standardize
* window.onerror so it works like you'd think.
*
* @see http://www.quirksmode.org/dom/events/error.html
*/
window.onanyerror = window.onanyerror || onanyerrorx;
/**
* Hook up all error handlers after window loads.
*/
function onload() {
handleGlobal();
handleXMLHttp();
handleImage();
handleScript();
handleEvents();
}
/**
* Handle global window events.
*/
function handleGlobal() {
var onerrorx = window.onerror;
window.addEventListener('error', onerror);
function onerror(msg, url, line, col, error) {
window.onanyerror.apply(this, arguments);
if (onerrorx) return onerrorx.apply(null, arguments);
}
}
/**
* Handle ajax request errors.
*/
function handleXMLHttp() {
var sendx = XMLHttpRequest.prototype.send;
window.XMLHttpRequest.prototype.send = function(){
handleAsync(this);
return sendx.apply(this, arguments);
};
}
/**
* Handle image errors.
*/
function handleImage() {
var ImageOriginal = window.Image;
window.Image = ImageOverride;
/**
* New `Image` constructor. Might cause some problems,
* but not sure yet. This is at least a start, and works on chrome.
*/
function ImageOverride() {
var img = new ImageOriginal;
onnext(function(){ handleAsync(img); });
return img;
}
}
/**
* Handle script errors.
*/
function handleScript() {
var HTMLScriptElementOriginal = window.HTMLScriptElement;
window.HTMLScriptElement = HTMLScriptElementOverride;
/**
* New `HTMLScriptElement` constructor.
*
* Allows us to globally override onload.
* Not ideal to override stuff, but it helps with debugging.
*/
function HTMLScriptElementOverride() {
var script = new HTMLScriptElement;
onnext(function(){ handleAsync(script); });
return script;
}
}
/**
* Handle errors in events.
*
* @see http://stackoverflow.com/questions/951791/javascript-global-error-handling/31750604#31750604
*/
function handleEvents() {
var addEventListenerx = window.EventTarget.prototype.addEventListener;
window.EventTarget.prototype.addEventListener = addEventListener;
var removeEventListenerx = window.EventTarget.prototype.removeEventListener;
window.EventTarget.prototype.removeEventListener = removeEventListener;
function addEventListener(event, handler, bubble) {
var handlerx = wrap(handler);
return addEventListenerx.call(this, event, handlerx, bubble);
}
function removeEventListener(event, handler, bubble) {
handler = handler._witherror || handler;
removeEventListenerx.call(this, event, handler, bubble);
}
function wrap(fn) {
fn._witherror = witherror;
function witherror() {
try {
fn.apply(this, arguments);
} catch(e) {
window.onanyerror.apply(this, e);
throw e;
}
}
return fn;
}
}
/**
* Handle image/ajax request errors generically.
*/
function handleAsync(obj) {
var onerrorx = obj.onerror;
obj.onerror = onerror;
var onabortx = obj.onabort;
obj.onabort = onabort;
var onloadx = obj.onload;
obj.onload = onload;
/**
* Handle `onerror`.
*/
function onerror(error) {
window.onanyerror.call(this, error);
if (onerrorx) return onerrorx.apply(this, arguments);
};
/**
* Handle `onabort`.
*/
function onabort(error) {
window.onanyerror.call(this, error);
if (onabortx) return onabortx.apply(this, arguments);
};
/**
* Handle `onload`.
*
* For images, you can get a 403 response error,
* but this isn't triggered as a global on error.
* This sort of standardizes it.
*
* "there is no way to get the HTTP status from a
* request made by an img tag in JavaScript."
* @see http://stackoverflow.com/questions/8108636/how-to-get-http-status-code-of-img-tags/8108646#8108646
*/
function onload(request) {
if (request.status && request.status >= 400) {
window.onanyerror.call(this, request);
}
if (onloadx) return onloadx.apply(this, arguments);
}
}
/**
* Generic error handler.
*
* This shows the basic implementation,
* which you could override in your app.
*/
function onanyerrorx(entity) {
var display = entity;
// ajax request
if (entity instanceof XMLHttpRequest) {
// 400: http://example.com/image.png
display = entity.status + ' ' + entity.responseURL;
} else if (entity instanceof Event) {
// global window events, or image events
var target = entity.currentTarget;
display = target;
} else {
// not sure if there are others
}
capture(entity);
console.log('[onanyerror]', display, entity);
}
/**
* Capture stuff for debugging purposes.
*
* Keep them in memory so you can reference them
* in the chrome debugger as `onanyerror0` up to `onanyerror99`.
*/
function capture(entity) {
captures.push(entity);
if (captures.length > 100) captures.unshift();
// keep the last ones around
var i = captures.length;
while (--i) {
var x = captures[i];
window['onanyerror' + i] = x;
}
}
/**
* Wait til next code execution cycle as fast as possible.
*/
function onnext(fn) {
setTimeout(fn, 0);
}
})();
Nó có thể được sử dụng như thế này:
window.onanyerror = function(entity){
console.log('some error', entity);
};
Tập lệnh đầy đủ có cài đặt mặc định cố gắng in ra một phiên bản "hiển thị" có thể đọc được của thực thể / lỗi mà nó nhận được. Có thể được sử dụng cho cảm hứng cho một trình xử lý lỗi dành riêng cho ứng dụng. Việc triển khai mặc định cũng giữ một tham chiếu đến 100 thực thể lỗi cuối cùng, vì vậy bạn có thể kiểm tra chúng trong bảng điều khiển web sau khi chúng xảy ra như:
window.onanyerror0
window.onanyerror1
...
window.onanyerror99
Lưu ý: Điều này hoạt động bằng cách ghi đè các phương thức trên một số trình xây dựng / trình tạo riêng. Điều này có thể có tác dụng phụ ngoài ý muốn. Tuy nhiên, nó rất hữu ích khi sử dụng trong quá trình phát triển, để tìm ra lỗi xảy ra ở đâu, gửi nhật ký đến các dịch vụ như NewRelic hoặc Sentry trong quá trình phát triển để chúng tôi có thể đo lường lỗi trong quá trình phát triển và để dàn dựng để chúng tôi có thể gỡ lỗi những gì đang diễn ra một mức độ sâu sắc hơn. Sau đó nó có thể được tắt trong sản xuất.
Hi vọng điêu nay co ich.
Người ta cũng nên duy trì cuộc gọi lại onerror liên quan trước đó
<script type="text/javascript">
(function() {
var errorCallback = window.onerror;
window.onerror = function () {
// handle error condition
errorCallback && errorCallback.apply(this, arguments);
};
})();
</script>
Nếu bạn muốn cách thống nhất để xử lý cả lỗi chưa được xử lý và từ chối lời hứa chưa được xử lý, bạn có thể xem thư viện chưa bị bắt .
BIÊN TẬP
<script type="text/javascript" src=".../uncaught/lib/index.js"></script>
<script type="text/javascript">
uncaught.start();
uncaught.addListener(function (error) {
console.log('Uncaught error or rejection: ', error.message);
});
</script>
Nó nghe cửa sổ. unandledrejection ngoài window.onerror.
Tôi khuyên bạn nên thử Trackjs .
Đó là lỗi đăng nhập như một dịch vụ.
Thật đơn giản để thiết lập. Chỉ cần thêm một dòng <script> vào mỗi trang và đó là dòng đó. Điều này cũng có nghĩa là sẽ rất đơn giản để xóa nếu bạn quyết định không thích nó.
Có những dịch vụ khác như Sentry (là nguồn mở nếu bạn có thể lưu trữ máy chủ của riêng mình), nhưng nó không làm được những gì Trackjs làm. Trackjs ghi lại sự tương tác của người dùng giữa trình duyệt của họ và máy chủ web của bạn để bạn thực sự có thể theo dõi các bước của người dùng dẫn đến lỗi, trái ngược với chỉ một tham chiếu số tệp và dòng (và có thể ngăn xếp dấu vết).
Bạn lắng nghe sự kiện onerror bằng cách gán một hàm cho window.onerror:
window.onerror = function (msg, url, lineNo, columnNo, error) {
var string = msg.toLowerCase();
var substring = "script error";
if (string.indexOf(substring) > -1){
alert('Script Error: See Browser Console for Detail');
} else {
alert(msg, url, lineNo, columnNo, error);
}
return false;
};