Preventing console errors - javascript

Whats the best approach for preventing errors when console.log calls have been left in JavaScript and it is executed on Browsers without a console or with console deactivated. Is there a way it can be automatically overridden to become a javascript alert for example?

if(!window.console) console = {log: function(s) {alert(s);}};
You can of course add more of the functions that console normally has.

You have to check if the console identifier is available, you can do it either by using the typeof operator, or by checking window.console, because if you access directly an identifier and it's not defined, you will get a ReferenceError.
For example:
if (typeof console == "undefined") {
window.console = {
log: function () {
// do nothing
}
};
console.warn = console.debug = console.log;
}

Here's what I use :-
if(typeof(console) != "undefined")

Related

Is it possible to override console logs

If I receive an error from a framework or an error from the browser. Basically a runtime error of any kind. Without modifying the framework, is it possible for me to override the console logs that these frameworks make and the browser's errors. I want to use my own framework with own error handling system when informing the user of errors of practically anything runtime (not syntax errors). I don't know if you would class it all as runtime errors because of the way javascript is executed in the browser but hopefully you will get me?
Is this possible if all the frameworks are written in Javascript?
How is this achieved?
What considerations do I have to make between different browsers?
Thanks
You are probably looking for a try-catch block:
try {
alert(foo);
} catch(e) {
alert('The code got the following error: '+e.message);
}
Whenever the code between the try {} receives an error, the catch(e) {} block will execute, with the argument e being the error object for the error that occurred. In this case, the variable foo is not defined, so executing this code will result in an alert message saying "The code got the following error: foo is not defined"
While not over-riding console.log, you may be achieve the same effect by overriding window.onerror.
From the MDN documentation
window.onerror = function myErrorHandler(errorMsg, url, lineNumber) {
// Log the error here -- perhaps using an AJAX call
}
You could try overriding the console.log() function.
//Save original reference
var originalConsole = console;
//Override
console = {};
console.log = function()
{
//According to MDN the console.log function can receive a variable number of params
for(var i=0; i<arguments.length; i++)
{
//Make your changes here, then call the original console.log function
originalConsole.log("Change something: "+arguments[i]);
}
//Or maybe do something here after parsing all the arguments
//...
}
console.log("one", "two");
JSFiddle here.
You can override the console logs by creating a "console" object and overriding it's .log() function:
var console = {};
console.log = function(){};
Some browsers require this to be added to the window object directly; so, for browser compatibility, also add:
window.console = console;
Additionally, you can override other console functions (e.g. console.info, console.warn and console.error) if you're using those too.
Also, consider reading this blog post from Udi Talias on overriding the console functions. Good and quick read!
You can custom your console.log here
// copy the original
let originalConsole = Object.assign({}, console);
// do something with your log.
console.log = (value) => {
//some cool condition
if (true) {
value = "new_log : " + value
}
originalConsole.log(value);
};

How can I avoid to write to the console?

I have to avoid to write console.log (also dir etc) in my server prod.
I've tried with
console = {};
But it doesn't work.
Try this bit of code:
var console = {
log : function (string) {
//does nothing
}
}
If often insert this piece of code to allow me to control console logging on client or server:
// must be in the global scope
if (typeof console === "undefined") {
var console = {};
}
if (!console.log) {
console.log = function() {
// put whatever you want here or nothing if you want to stub it out
}
}
Then, any console.log() statements will simply do nothing.
Doing it this way, allows code to actually use the real console.log() if it is defined, but prevents any errors if it is not defined.

IE8 console log - stub if dev tools not open, but use if dev tools is open?

I'm using the following stub to protect against leaving console.log statements in a production application:
// Protect against IE8 not having developer console open.
var console = console || {
"log": function () {
},
"error": function () {
},
"trace": function () {
}
};
This works fine in the sense that it prevents exceptions from being thrown when I call console.log in IE8 without the developer tools open. However, I dislike the fact that if I open dev. tools after the code has loaded -- I still don't see my log messages.
Is it possible to have both? My attempts have led me to infinite recursions of console.log calls. I also found this: http://log4javascript.org/ but I'd rather not unless entirely necessary
EDIT: To clarify: I simply want to not throw an exception if dev. console isn't open, but use the console if it is opened later.
Yes, you could do something like:
if (typeof(console) === "undefined") {
var console = {
log: function() { },
error: function() { },
trace: function() { }
};
}
Make a wrapper function and call it instead of console.log.
function log(msg) {
var console = window.console;
if (console && typeof console.log === 'function') {
console.log(msg);
}
}
This way, it is not going to override window.console and make it not available later.

Override console.log in coffeescript

Sometimes we leave console.log debug statements in our javascript. Just so they don't accidentally make it into production (where some old browsers will die on these), we tried doing this in our first coffeescript file:
if !console?
console = {log: ->}
But this seems to kill all ability to use console.log in development, even in browsers that support it (webkit).
console? returns false, so the if block doesn't run, but it still seems to overwrite the functionality of console.log.
Any ideas? Thanks!
The problem is that this:
if !console?
console = {log: ->}
becomes this JavaScript:
var console;
if (typeof console === "undefined" || console === null) {
console = {
log: function() {}
};
}
The result is that you have a local console variable that shadows the window.console that you're looking for.
The solution is to say exactly what you mean:
if 'console' !of window
window.console = { log: -> }
Note that console is always localized to window here so you don't accidentally create any shadows.
There are various ways to say if 'console' !of window that will have the same effect, use whichever one is clearest for you.
My approach has been to define a DEBUG (or print) function to use instead of console.log. The default, production definition is
DEBUG = () ->
and prior to any test code (e.g. at the end like Python if __name__... block):
if not module.parent? and (!process.argv[2]? or process.argv[2]!='nodebug')
DEBUG = (arg...) ->
arg.unshift('==> ')
console.log arg...
or simply
DEBUG = console.log

Why doesn't JavaScript function aliasing work?

I have some Firebug console function calls that I wanted to disable when Firebug wasn't enabled, e.g. console isn't defined. This works fine in IE6 and FF3, but not in Chrome:
var log;
if(console){
log = console.log;
}else{
log = function(){ return; }
}
I get an "Uncaught TypeError: Illegal Invocation" in Chrome =/
I read about the issue here, where you have to apply a context, which is kind of new to me... and I can't seem to figure how to accomplish the above in all browsers...
Yes, you should persist the context :
var log;
if (window.console && typeof console.log === "function"){
// use apply to preserve context and invocations with multiple arguments
log = function () { console.log.apply(console, arguments); };
} else {
log = function(){ return; }
}
What is happening is that the context (the this value), is implicitly set when you call a function, for example:
var obj = {
method: function () { return this; }
};
obj.method() === obj; // true
In this case, you are calling a function that is defined as a property of an object, when the function is invoked, the this value is set to that object.
Now as in your example, if you copy a reference of that method to a variable:
var method = obj.method;
method() === window; // global object
As you can see, the this value refers to the global object.
So, to avoid this implicit behavior you can set the context explicitly, with the call or apply functions.
The problem with wrapping a function (like console.log) in a function is that it loses its context, i.e. it will not show the correct line number of the file that we've put our "log" shortcut in.
Instead I suggest something like this:
window.log = ((window.console && window.console.log) ?
console.log.bind(console) :
function(){});
This works with firebug & chrome dev tools and does not throw errors when no console is available. And - most importantly - shows the correct file & line number.
This doesn't work:
log("hi");
While this does:
log.call(console, "hi");
It is obvious that you need to call the aliased function with the correct context -- as you yourself have mentioned.
I think you'll have to use a function wrapper (a closure that has a reference to the original context) rather than an alias...
Update
Also note that if you check for console directly, you may get a run-time error when the variable doesn't exist. You're better off checking it explicitly as window.console. Here's one way to implement a conditional log wrapper:
var log = (function (console) {
return console
? function () { console.log.apply(console, arguments); }
: function () {}
})(window.console);
This solution modifies the earlier and excellent answer from CMS to work with IE8. You’ll need to open the IE8 console (press F12) before executing this. (If you forget, you’ll need to exit IE8 entirely and start again because even if the console exists, IE8 won’t subsequently create the console object.)
Note that we don’t set the context, which was the original problem but, as it turns out, IE8 doesn’t require that context. (Good thing, because IE8 also doesn’t provide the apply method on the console.log object!).
This code works with the latest versions of Chrome, FireFox, and MSIE. (It is compatible with MSIE6 and doesn’t throw an error.)
if((typeof console !== "undefined") && ((typeof console.log) !== "undefined"))
{
if ((typeof console.log.apply !== "undefined"))
{
log = function() { console.log.apply(console,arguments) };
}
else
{
log = console.log;
}
}
else
{
log = function() {};
// alert("No debug console");
}
I did this
var log;
log = function() {
if ((window.console != null) && (window.console.log.apply != null)) {
return console.log.apply(console, arguments);
} else {
return function() {};
}
};

Categories