A few weeks ago I was asked to try and clean up our production client's console. The crux was that I only had a few hours to do it.

The solution needed to suppress and log messages from several third party libraries, support our legacy code base and it's logging implementation, catch any Angular errors that occurred, as well as provide full stack traces for our server side logging mechanism.

The solution

In the face of this complexity and a tight deadline we needed a simple solution. We decided to override the existing console.* messaging methods with a small snipet of code, that would check a log level before posting to the console and that would generate an error with a stack trace in order to log it to the server.

It looks something like this.

function overRide(type) {
    return (function(message) {
        if (clientLogLevel >= level[type]) {
            var curArguments = formatColours(arguments);
            defaults[type].apply(console, curArguments);
        logError(generateError(type, message));

Catching global errors

Whilst this solution was elegant we still needed to implement the window.onerror event handler to catch any run time script errors that might occur. Like all good things in JavaScript browser support is still mixed and the Error object wont always be returned.

window.onerror = function(message, url, lineNumber, columnNumber, errObj) {
    if (!errObj) {
        errObj = new errObj();
        errObj.message = message;
        errObj.lineNumber = lineNumber;

    // If no errObj type exists this errObj has bubbled to the
    // window object and needs to be logged to console.
    if (!errObj.type && errObj.message) {
        defaults.error.apply(console, errObj.message);
        errObj.type = 'error';

    // Log Message to the Server
    return logError(errObj);

Draw backs and benefits

There were some obvious benefits to this solution: it allows us to adopt the standard JavaScript work-flow for handling errors and logging messages as well as catching all messages to the console regardless of the origin.

There are a few drawbacks to this however, the largest being that the stack traces, as well as the message source file and line are muddied by the logger its self.

Where to find it

The full implementation can be found on GitHub along with a few usage examples.

Further Reading

David Walsh's article on forcing stack traces in JavaScript.

  • Last Updated: 14 September 2014
  • Tagged: #Javascript #Logging
  • Share This: Google+ - Twitter