I would like to check if a certain console error has occurred using javascript, and alert() myself if it has.
The error will look like this:
00:00:34:0359 TimeEvent.COMPLETE
(anonymous function) # VM17617:1
And the algorithm will look something like this:
function checkError(console) {
if(console.error === "TimeEvent.COMPLETE") {
alert("The error is present");
}
}
I'm not very familiar with the console, and haven't gotten much further with Google research. Can somebody point me in the right direction?
I ultimately solved my question by following this blog post on taking over the console with javascript.
Here is my final code:
var original = window.console
window.console = {
error: function(){
//Gets text from error message.
errorText = arguments['0'];
if (errorText.includes('TimeEvent.COMPLETE')) {
//DO STUFF HERE
}
original.error.apply(original, arguments)
}
}
You didn't provide the whole picture about how and when the console is getting the error. If you raise the error yourself, or if you are able to catch it inside a try catch, that would be the best place to intercept those errors.
However, if you have no control about how those error are raised, you should try to intercept your console's error calls. I never tried it myself but this SO answer explains how to intercept the console's log calls. Knowing that the console usually have a function named error that is similar to the log function, I'm sure you could apply the same logic to intercept the errors sent to the console.
If you are using chrome, you may refer to the console documentation for more details about the error function. I'm not sure if there's a standard butInternet Explorer and Firefox also has support for console error function.
The Chrome debugging tools are great most of the time, but lately I've been annoyed with errors that are rethrown. There doesn't seem to be any way to see the call stack unless you have it set to pause on caught exceptions, but then you run into gobs of errors from other libraries. It makes pausing on exceptions pretty useless if you want to display errors nicely.
Consider this example (http://jsfiddle.net/redbmk/83y8L/1/):
HTML:
<button id="push-me"></button>
Javascript:
function beDangerous() {
var one = 1, rand = parseInt(Math.random() * 2);
if (rand === one) console.log("You Win");
else if (rand === zero) console.log("You Lose");
}
function warnUser(error) {
alert("Hey, something went wrong! Refresh the page");
throw error;
}
function runCode() {
try {
beDangerous();
} catch (e) {
warnUser(e);
}
}
document.getElementById("push-me").addEventListener("click", runCode);
When you run into an error, the call stack shows you that warnUser threw an error and was called by runCode. There's no way to trace it back to beDangerous and see what the variables were at that point. You can see the stack trace, but only by looking at error.stack, and that doesn't give you any context. Replacing throw error with debugger doesn't seem to help (and that wouldn't allow you to turn off debugging).
Is there a better way to do this? It's been bugging me for a while now.
By the way, this question says to throw error.stack, but that doesn't work for me (and as I understand it the stack property is non-standard anyway, so this wouldn't work correctly for other browsers). This question says it's a known bug in Chrome that is marked as being fixed in version 19, but this is happening for me on version 35.
This is a different, but also known bug in Chrome, unfortunately, it is marked as wontfix. Looks like Firefox dev tools have same problem too.
is it possible to register an error or exception handler/function that will be executed when a javascript error or exception occurs? I just feel wrapping all codes in try/catch block seems very tedious and inefficient.
window.onerror = function (msg, file, line) {
// handle error here
}
Supported by:
Chrome 13+
Firefox 6.0+
Internet Explorer 5.5+
Opera 11.60+
Safari 5.1+
Andy E's answer (+1) tells you how to do it.
That said, JavaScript isn't really meant to have caught execeptions in the same sense that, say, Java does. If your code is throwing exceptions, pull up a console and use the debugger to fix them. JS exceptions are slow, and really not meant to be used for flow control. A method won't throw an exception unless there's a serious problem — and it's usually a programming error.
Here's an alternative answer than the window.onerror solution. This isn't something I've used in production, but is something that I just like because of the flexibility (i.e. you could use it to debug things like timing how long a method took or something).
Whilst you could probably pass window into it (don't quote me on that, and don't think it's a good idea) it does work if you have all your methods in an object:
(function(obj) {
for (var name in obj) {
if (typeof(obj[name]) == 'function') {
currentMethod = obj[name];
obj[name] = function() {
try {
currentMethod();
}
catch (e) {
alert('Exception Handler: ' + e);
}
};
}
}
}(myObject));
Here's it working: http://jsfiddle.net/jonathon/kpYnW/
Basically, it goes through each property in your object, finds the ones that are functions and wraps them in a try/catch (or whatever else you want).
Whether or not it's efficient is a different matter - I've just found it a very useful technique for debugging. Unfortunately I can't remember the original place I read it but if anyone knows, please add as a comment.
I have a bunch of console.log() calls in my JavaScript.
Should I comment them out before I deploy to production?
I'd like to just leave them there, so I don't have to go to the trouble of re-adding the comments later on if I need to do any more debugging. Is this a bad idea?
It will cause Javascript errors, terminating the execution of the block of Javascript containing the error.
You could, however, define a dummy function that's a no-op when Firebug is not active:
if(typeof console === "undefined") {
console = { log: function() { } };
}
If you use any methods other than log, you would need to stub out those as well.
As others have already pointed it, leaving it in will cause errors in some browsers, but those errors can be worked around by putting in some stubs.
However, I would not only comment them out, but outright remove those lines. It just seems sloppy to do otherwise. Perhaps I'm being pedantic, but I don't think that "production" code should include "debug" code at all, even in commented form. If you leave comments in at all, those comments should describe what the code is doing, or the reasoning behind it--not blocks of disabled code. (Although, most comments should be removed automatically by your minification process. You are minimizing, right?)
Also, in several years of working with JavaScript, I can't recall ever coming back to a function and saying "Gee, I wish I'd left those console.logs in place here!" In general, when I am "done" with working on a function, and later have to come back to it, I'm coming back to fix some other problem. Whatever that new problem is, if the console.logs from a previous round of work could have been helpful, then I'd have spotted the problem the first time. In other words, if I come back to something, I'm not likely to need exactly the same debug information as I needed on previous occasions.
Just my two cents... Good luck!
Update after 13 years
I've changed my mind, and now agree with the comments that have accumulated on this answer over the years.
Some log messages provide long-term value to an application, even a client-side JavaScript application, and should be left in.
Other log messages are low-value noise and should be removed, or else they will drown out the high-value messages.
If you have a deployment script, you can use it to strip out the calls to console.log (and minify the file).
While you're at it, you can throw your JS through JSLint and log the violations for inspection (or prevent the deployment).
This is a great example of why you want to automate your deployment. If your process allows you to publish a js file with console.logs in it, at some point you will do it.
To my knowledge there is no shorter method of stubbing out console.log than the following 45 characters:
window.console||(console={log:function(){}});
That's the first of 3 different versions depending on which console methods you want to stub out all of them are tiny and all have been tested in IE6+ and modern browsers.
The other two versions cover varying other console methods. One covers the four basics and the other covers all known console methods for firebug and webkit. Again, in the tiniest file sizes possible.
That project is on github: https://github.com/andyet/ConsoleDummy.js
If you can think of any way to minimize the code further, contributions are welcomed.
-- EDIT -- May 16, 2012
I've since improved on this code. It's still tiny but adds the ability to turn the console output on and off: https://github.com/HenrikJoreteg/andlog
It was featured on The Changelog Show
You should at least create a dummy console.log if the object doesn't exist so your code won't throw errors on users' machines without firebug installed.
Another possibility would be to trigger logging only in 'debug mode', ie if a certain flag is set:
if(_debug) console.log('foo');
_debug && console.log('foo');
Hope it helps someone--I wrote a wrapper for it a while back, its slightly more flexible than the accepted solution.
Obviously, if you use other methods such as console.info etc, you can replicate the effect. when done with your staging environment, simply change the default C.debug to false for production and you won't have to change any other code / take lines out etc. Very easy to come back to and debug later on.
var C = {
// console wrapper
debug: true, // global debug on|off
quietDismiss: false, // may want to just drop, or alert instead
log: function() {
if (!C.debug) return false;
if (typeof console == 'object' && typeof console.log != "undefined") {
console.log.apply(this, arguments);
}
else {
if (!C.quietDismiss) {
var result = "";
for (var i = 0, l = arguments.length; i < l; i++)
result += arguments[i] + " ("+typeof arguments[i]+") ";
alert(result);
}
}
}
}; // end console wrapper.
// example data and object
var foo = "foo", bar = document.getElementById("divImage");
C.log(foo, bar);
// to surpress alerts on IE w/o a console:
C.quietDismiss = true;
C.log("this won't show if no console");
// to disable console completely everywhere:
C.debug = false;
C.log("this won't show ever");
this seems to work for me...
if (!window.console) {
window.console = {
log: function () {},
group: function () {},
error: function () {},
warn: function () {},
groupEnd: function () {}
};
}
Figured I would share a different perspective. Leaving this type of output visible to the outside world in a PCI application makes you non-compliant.
I agree that the console stub is a good approach. I've tried various console plugins, code snippets, including some fairly complex ones. They all had some problem in at least one browser, so I ended up going with something simple like below, which is an amalgamation of other snippets I've seen and some suggestions from the YUI team. It appears to function in IE8+, Firefox, Chrome and Safari (for Windows).
// To disable logging when posting a production release, just change this to false.
var debugMode = false;
// Support logging to console in all browsers even if the console is disabled.
var log = function (msg) {
debugMode && window.console && console.log ? console.log(msg) : null;
};
Note: It supports disabling logging to the console via a flag. Perhaps you could automate this via build scripts too. Alternatively, you could expose UI or some other mechanism to flip this flag at run time. You can get much more sophisticated of course, with logging levels, ajax submission of logs based on log threshold (e.g. all Error level statements are transmitted to the server for storage there etc.).
Many of these threads/questions around logging seem to think of log statements as debug code and not code instrumentation. Hence the desire to remove the log statements. Instrumentation is extremely useful when an application is in the wild and it's no longer as easy to attach a debugger or information is fed to you from a user or via support. You should never log anything sensitive, regardless of where it's been logged to so privacy/security should not be compromised. Once you think of the logging as instrumentation it now becomes production code and should be written to the same standard.
With applications using ever more complex javascript I think instrumentation is critical.
As other have mentions it will thrown an error in most browsers. In Firefox 4 it won't throw an error, the message is logged in the web developer console (new in Firefox 4).
One workaround to such mistakes that I really liked was de&&bug:
var de = true;
var bug = function() { console.log.apply(this, arguments); }
// within code
de&&bug(someObject);
A nice one-liner:
(!console) ? console.log=function(){} : console.log('Logging is supported.');
Yes, it's bad idea to let them running always in production.
What you can do is you can use console.debug which will console ONLY when the debugger is opened.
https://developer.mozilla.org/en-US/docs/Web/API/console/debug
function testFun() {
onerror = function() { log("caught the error"); return true; };
setTimeout(function() { throw "bad bad bad"; }, 300);
};
This is sample, code, but it demonstrates a problem.
If I run this in FF, or IE7, it prints the sensible "caught the error" message (assume a reasonable 'log' function).
However if I debug the code in VS2008, the debugger stops on the throw with the message: 'Microsoft JScript runtime error: Exception thrown and not caught'. If I say 'continue' or 'ignore', the log message is not produced.
This is a problem since the real code I am working with is much larger than this, and I'll occasionally want to, you know, debug stuff. So two questions:
Any know why and can I modify this behaviour with some flag I don't know about?
Am I doing what I think I'm doing (setting the global 'onerror' handler) in this code? If not, what is the appropriate pattern for catching this type of error?
Note: There is no difference wrt this problem if I use window.onerror instead.
According to this defining a global onerror function doesn't work in IE. They were probably talking about IE6 or earlier, so maybe MS have fixed it for IE7 - however I wouldn't expect this to just automatically flow through to the VS debugger.
At any rate, try using window.onerror = function rather than just onerror.
If that doesn't work, you'll have to use a try/catch block inside your timer function I guess.
PS: Get firefox and use firebug. the debugger (and everything else) is much better and nicer to use than the VS debugging