I would like to catch every undefined function error thrown. Is there a global error handling facility in JavaScript? The use case is catching function calls from flash that are not defined.
-
What do you want to do with an error once you catch it? Do you just need to log it so you can create the missing function, or are you looking to stop exceptions from breaking your code? – Dan Herbert Jun 04 '09 at 17:00
-
2I would like to get the name of the missing function called and based on presence of some string call my own function. Any call to a function with the string 'close' would call my close() for example. I would also like to trap the error at that point. – Jun 04 '09 at 17:06
-
2https://exceptionsjs.com provides this functionality and can be taylored to only catch errors related to undefined functionality with its "guard" functionality. – Steven Wexler Aug 04 '14 at 02:48
9 Answers
How to Catch Unhandled Javascript Errors
Assign the window.onerror
event to an event handler like:
<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>
As commented in the code, if the return value of window.onerror
is true
then the browser should suppress showing an alert dialog.
When does the window.onerror Event Fire?
In a nutshell, the event is raised when either 1.) there is an uncaught exception or 2.) a compile time error occurs.
uncaught exceptions
- throw "some messages"
- call_something_undefined();
- cross_origin_iframe.contentWindow.document;, a security exception
compile error
<script>{</script>
<script>for(;)</script>
<script>"oops</script>
setTimeout("{", 10);
, it will attempt to compile the first argument as a script
Browsers supporting window.onerror
- Chrome 13+
- Firefox 6.0+
- Internet Explorer 5.5+
- Opera 11.60+
- Safari 5.1+
Screenshot:
Example of the onerror code above in action after adding this to a test page:
<script type="text/javascript">
call_something_undefined();
</script>
Example for AJAX error reporting
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));
JSFiddle:
https://jsfiddle.net/nzfvm44d/
References:
- Mozilla Developer Network :: window.onerror
- MSDN :: Handling and Avoiding Web Page Errors Part 2: Run-Time Errors
- Back to Basics – JavaScript onerror Event
- DEV.OPERA :: Better error handling with window.onerror
- Window onError Event
- Using the onerror event to suppress JavaScript errors
- SO :: window.onerror not firing in Firefox

- 3,031
- 2
- 28
- 30

- 26,946
- 12
- 75
- 101
-
3worth mentionning firefox doesn't give back the error message when `throw` is made manually. http://stackoverflow.com/questions/15036165/catching-error-event-message-from-firefox – Sebas Mar 30 '13 at 02:09
-
2Great answer. You can implement the "Report this error via ajax" with a package like JSNLog, which does the ajax and server side logging for you. – user1147862 Nov 16 '13 at 10:02
-
4In addition to this answer, I added the err object so I could get the stack trace. http://stackoverflow.com/a/20972210/511438. Now I can develop with more feedback because my dev errors appear as a box at the top of the page (as I have created it). – Valamas Jun 23 '14 at 03:02
-
Wouldn't it be better to pack your onerror implementation in a try-catch(ignore) block, preventing your onerror() to throw even more errors? (not that it's the case here, but just to be sure) – Pieter De Bie Aug 14 '15 at 08:57
-
-
@Pacerier You can use `error instanceof SyntaxError`. See [MDN instanceof docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof) and [MDN SyntaxError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError). Not sure what the older browser support is for this, but MDN suggests it's supported across the board. – Sam Feb 17 '17 at 20:53
-
As you say, this handles *unhandled* errors. If a library is catching an error and making an alert or something, the error won't make it to window.onerror. – Noumenon Oct 11 '17 at 18:32
-
it does not work now as Nov 2017, error in latest Chrome and IE 11 does not get captured by global error handler – super1ha1 Nov 16 '17 at 03:53
-
1@super1ha1 Can you provide a jsfiddle? I don't think browsers would introduce a breaking change where the onerror event handler stops firing events. You can try this jsfiddle to see the onerror handler working: https://jsfiddle.net/nzfvm44d/ This still works for me in Chrome version 62.0.3202.94 (Official Build) (64-bit). – Sam Nov 17 '17 at 17:36
-
What is the syntax if I want a named function? window.onerror=MyErrorFunction – Cymro Dec 24 '19 at 13:28
-
@Sam about the browser support section of your great answer, what was your source, even linked MDN page is not same as yours. – Mehdi Dehghani Jan 20 '20 at 12:19
-
@MehdiDehghani it looks like I got it from https://dev.opera.com/articles/better-error-handling-with-window-onerror/ . Generally speaking I go with the docs in MDN, but I'm certain IE had support for this before IE9. It's shocking to me that the docs for this event aren't better. Hopefully they're better now than they were when I answered this 8 yrs ago. – Sam May 13 '20 at 23:19
-
This does not work for errors fired inside a dynamically populated iframe, any workaround for that? – raquelhortab Dec 21 '21 at 10:33
-
@raquelhortab You need to capture the error within the iframe using a global error handler like this post discusses. Once you capture the error in the iframe, it's up to you what you want to do with it. You can ajax the error to capture it on a server or communicate the error to the main window (example https://stackoverflow.com/questions/9153445/how-to-communicate-between-iframe-and-the-parent-site). – Sam Dec 21 '21 at 21:42
Does this help you:
<script type="text/javascript">
window.onerror = function() {
alert("Error caught");
};
xxx();
</script>
I'm not sure how it handles Flash errors though...
Update: it doesn't work in Opera, but I'm hacking Dragonfly right now to see what it gets. Suggestion about hacking Dragonfly came from this question:

- 1
- 1

- 176,118
- 18
- 189
- 202
-
3With the addition of msg, file_loc, line_no params this should do it for me. Thanks! – Jun 04 '09 at 17:16
-
2Do I understand correctly that this code overrides any existing error handlers? – Mars Robertson Jan 27 '17 at 15:27
-
-
@atilkan`window.onerror = function() { alert(42) };` now the code in the answer: `window.onerror = function() { alert("Error caught"); };` not overriden, I'm still unsure.. – Mars Robertson Nov 20 '19 at 15:31
-
1@MarsRobertson I understand. It probably overwrites. Yes, it does, just tested. Using addEventListener would be better. – atilkan Nov 21 '19 at 14:15
sophisticated error handling
If your error handling is very sophisticated and therefore might throw an error itself, it is useful to add a flag indicating if you are already in "errorHandling-Mode". Like so:
var appIsHandlingError = false;
window.onerror = function() {
if (!appIsHandlingError) {
appIsHandlingError = true;
handleError();
}
};
function handleError() {
// graceful error handling
// if successful: appIsHandlingError = false;
}
Otherwise you could find yourself in an infinite loop.

- 3,525
- 4
- 36
- 57
-
30Or a more fail-safe way would be to use try-catch around the `handleError` method. – Aidiakapi Apr 26 '12 at 14:49
-
8You can't use try catch if you have ansynchronous call in you'r error handling. So he's solution remain e good solution – Emrys Myrooin Jul 03 '15 at 13:04
-
@EmrysMyrooin Still it will cause a sync or an async loop by error handling and probably crash without usable stack info. – inf3rno Aug 25 '16 at 22:11
-
1I think the flag should be reset at some point, right? I believe we need a try/catch around if big if, and make sure the flag is reset right before leaving the onerror method. Otherwise, only one error will be handled. – Seb Mar 10 '17 at 17:39
It seems that window.onerror
doesn't provide access to all possible errors. Specifically it ignores:
<img>
loading errors (response >= 400).<script>
loading errors (response >= 400).- global errors if you have many other libraries in your app also manipulating
window.onerror
in an unknown way (jquery, angular, etc.). - probably many cases I haven't run into after exploring this now (iframes, stack overflow, etc.).
Here is the start of a script that catches many of these errors, so that you may add more robust debugging to your app during development.
(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);
}
})();
It could be used like this:
window.onanyerror = function(entity){
console.log('some error', entity);
};
The full script has a default implementation that tries to print out a semi-readable "display" version of the entity/error that it receives. Can be used for inspiration for an app-specific error handler. The default implementation also keeps a reference to the last 100 error entities, so you can inspect them in the web console after they occur like:
window.onanyerror0
window.onanyerror1
...
window.onanyerror99
Note: This works by overriding methods on several browser/native constructors. This can have unintended side-effects. However, it has been useful to use during development, to figure out where errors are occurring, to send logs to services like NewRelic or Sentry during development so we can measure errors during development, and on staging so we can debug what is going on at a deeper level. It can then be turned off in production.
Hope this helps.
-
1Apparently images trigger the error event: http://stackoverflow.com/a/18152753/607033 – inf3rno Aug 25 '16 at 22:05
-
Let me explain how to get stacktraces that are reasonably complete in all browsers.
Error handling in JavaScript
Modern Chrome and Opera fully support the HTML 5 draft spec for ErrorEvent and window.onerror
. In both of these browsers you can either use window.onerror
, or bind to the 'error' event properly:
// 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);
})
Unfortunately Firefox, Safari and IE are still around and we have to support them too. As the stacktrace is not available in window.onerror
we have to do a little bit more work.
It turns out that the only thing we can do to get stacktraces from errors is to wrap all of our code in a try{ }catch(e){ }
block and then look at e.stack
. We can make the process somewhat easier with a function called wrap that takes a function and returns a new function with good error handling.
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;
};
This works. Any function that you wrap manually will have good error handling, but it turns out that we can actually do it for you automatically in most cases.
By changing the global definition of addEventListener
so that it automatically wraps the callback we can automatically insert try{ }catch(e){ }
around most code. This lets existing code continue to work, but adds high-quality exception tracking.
var addEventListener = window.EventTarget.prototype.addEventListener;
window.EventTarget.prototype.addEventListener = function (event, callback, bubble) {
addEventListener.call(this, event, wrap(callback), bubble);
}
We also need to make sure that removeEventListener
keeps working. At the moment it won't because the argument to addEventListener
is changed. Again we only need to fix this on the prototype
object:
var removeEventListener = window.EventTarget.prototype.removeEventListener;
window.EventTarget.prototype.removeEventListener = function (event, callback, bubble) {
removeEventListener.call(this, event, callback._wrapped || callback, bubble);
}
Transmit error data to your backend
You can send error data using image tag as follows
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;
}

- 5,377
- 1
- 22
- 43

- 88,237
- 28
- 143
- 153
-
What is _yourserver.com/jserror_ ? *REST, Web Service, Wcf Service* ? Any simple about backend? – Kiquenet Sep 24 '15 at 11:32
-
If you want to send js errors from user browser to your server. you have to write your backend(`http://yourserver.com`) to receive and store. If you choose https://www.atatus.com/, you dont need to do anything. Just include two lines of script in your page. – Fizer Khan Sep 25 '15 at 06:53
// display error messages for a page, but never more than 3 errors
window.onerror = function(msg, url, line) {
if (onerror.num++ < onerror.max) {
alert("ERROR: " + msg + "\n" + url + ":" + line);
return true;
}
}
onerror.max = 3;
onerror.num = 0;

- 71,848
- 143
- 435
- 658
If you want unified way to handle both uncaught errors and unhandled promise rejections you may have a look on uncaught library.
EDIT
<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>
It listens window.unhandledrejection
in addition to window.onerror.

- 5,377
- 1
- 22
- 43

- 107
- 1
- 4
-
2Lance Pollard in [the answer above](https://stackoverflow.com/a/36317375/52277) mentioned a few errors, that normal onerror doesn’t handle. Does you library handle them? If some of them, please specify which? – Michael Freidgeim May 04 '19 at 23:07
-
@MiFreidgeimSO-stopbeingevil Just checked the source code - no unfortunately it doesn't. Aleksandr Oleynikov: Would be awesome if you can support this - I'll then turn my downvote to an upvote ;-) – brillout Apr 01 '20 at 06:51
One should preserve the previously associated onerror callback as well
<script type="text/javascript">
(function() {
var errorCallback = window.onerror;
window.onerror = function () {
// handle error condition
errorCallback && errorCallback.apply(this, arguments);
};
})();
</script>

- 4,086
- 10
- 30
- 46
I would recommend giving Trackjs a try.
It's error logging as a service.
It's amazingly simple to set up. Just add one <script> line to each page and that's it. This also means it will be amazingly simple to remove if you decide you don't like it.
There are other services like Sentry (which is open-source if you can host your own server), but it doesn't do what Trackjs does. Trackjs records the user's interaction between their browser and your webserver so that you can actually trace the user steps that led to the error, as opposed to just a file and line number reference (and maybe stack trace).
-
2TrackJS [doesn't seem to have a free tier](https://trackjs.com/pricing/) anymore, though there is a free trial. – pkaeding May 24 '15 at 21:52
-
This is fine for tracking and being alerted to errors but doesn't really solve the handling part. Ideally I think the asker is looking for a way to handle these errors so that the rest of the code still runs. – wgp Aug 30 '15 at 17:43
-
What if you catch the error event and add an xhr call to the logger with the stack trace and the application state? How is trackjs better? – inf3rno Aug 25 '16 at 22:09
-
2@inf3rno it's more than a stack trace, which just tracks the beginning of the error. TrackJS will track the entire user session so you can see what led up to it. here's a screenshot as an example https://trackjs.com/assets/images/screenshot.png – kane Aug 26 '16 at 15:47