14 Jan 2011

(Fix) Javascript: Avoiding “console is undefined”

Author: Ben Adams | Filed under: Development

Testing if a function or object is defined can sometimes cause as many errors as not doing so. What to do?

When developing JavaScript using either Firebug in Firefox or Chrome’s built-in console you will probably at some point be using console.log either for debugging messages or for exception information.

However, when you come to run this code in Internet Explorer, it throws an exception “console is undefined”:

try {
    ... // code throwing error
} catch (e) {
    console.log(e); // throws script error "console is undefined"
}

“A-ha” you think; “easily solved will just test if its defined before use”. However things are not so straight forward:

try {
    ... // code throwing error
} catch (e) {
    if (console && console.log) // throws script error "console is undefined"
        console.log(e);
}

Even though now you are testing to see if it exists before use, you still get:

Console is undefined

While this would normally work for attributes of objects, globally scoped variables work differently. Luckily, all variables in global scope will be declared as attributes on the global window variable. This enables you to test for existence on the window.

Here we’ve wrapped the test up in a LogException function to ease changing of logging methodologies:

function LogException(e) {
    if (window.console // check for window.console not console
         && window.console.log) window.console.log(e);
    // Other logging here
}

try {
    ... // code throwing error
} catch (e) {
    LogException(e); // works fine
}

Note: Its isn’t exclusive to Internet Explorer, it just most visible there; so checking existence of globally scoped functions and variables against window rather than just by name is good practice!

Tags: , , ,

One Response to “(Fix) Javascript: Avoiding “console is undefined””

  1. HonoredMule Says:

    This has actually been an area I’ve explored rather exhaustively myself. I actually wanted to enjoy the advantages of all the console capabilities like sprintf-like string building, in-message object references, timing/profiling, html or styling in log messages, etc. available in some browsers and (in some cases) exclusively in Firebug, so I wrote a complete wrapper object/module for the console, the latest iteration of which can be seen in the dev snapshot of Butler (as the module BLog).

    Instead of wrapping just functions, I wrote various underlying implementations of the entire API I wanted to support, hidden inside a Yahoo Module patterned object. Then for optimal performance, I was able to determine what native functionality was available and assign the appropriate implementation on startup (initialization of the module). That detail (a dependency-aware bootstrapping system) is another conversation.

    This way the path to native functionality was minimal, the branching/condition testing during actual operation also minimal, the reliably-supported functionality maximized, and as a bonus I could maintain my own detailed in-UI logging facility with a rolling log of all intercepted log events/messages. Wrapping the whole logging facility as opposed to a single log function also allowed greater number of log levels using descriptive function names and the ability to filter the view of log history and use of native functions by client-adjustable log levels.

    Of course my version of IE dies when any 1.4.x jQuery is used, meaning Butler and even Illyriad itself won’t even start to run anyway, but in isolation from those factors, it works great. :)

Leave a Reply