27

I'm trying to write handler for uncaught exceptions and browser warnings in Javascript. All errors and warnings should be sent to server for later review.

Handled exceptions can be caught and easily logged with

console.error("Error: ...");

or

console.warn("Warning: ...");

So they are not problem if they are called from javascript code, even more, unhandled exceptions could be caught with this peace of code:

window.onerror = function(){
    // add to errors Stack trace etc.
   });
}

so exceptions are pretty covered but I've stuck with warnings which browser sends to console. For instance security or html validation warnings. Example below is taken from Google Chrome console

The page at https://domainname.com/ ran insecure content from http://domainname.com/javascripts/codex/MANIFEST.js.

It would be great if there is some event like window.onerror but for warnings. Any thoughts?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Milan Jaric
  • 5,556
  • 2
  • 26
  • 34
  • I was wondering the same thing. Logging negative resource request outcomes would be great, too. :) – SimplGy Mar 08 '13 at 04:47

6 Answers6

22

You could just wrap the console methods yourself. For example, to record each call in an array:

var logOfConsole = [];

var _log = console.log,
    _warn = console.warn,
    _error = console.error;

console.log = function() {
    logOfConsole.push({method: 'log', arguments: arguments});
    return _log.apply(console, arguments);
};

console.warn = function() {
    logOfConsole.push({method: 'warn', arguments: arguments});
    return _warn.apply(console, arguments);
};

console.error = function() {
    logOfConsole.push({method: 'error', arguments: arguments});
    return _error.apply(console, arguments);
};
Jeremy
  • 1
  • 85
  • 340
  • 366
  • 2
    I was thinking on this but it wont work for some of my expectations, for instance, while everything loads into secured page i will get plenty of warnings when some unsecured content is loaded, and that comes from browser, not javascript code. Also I want to cover stupid IE (which is why this came to my mind) and console is undefined there. Anyway you got vote from me :) – Milan Jaric Nov 03 '11 at 18:41
  • For IE use `var message = Array.prototype.slice.apply(arguments).join(' '); return _error(message);` etc. – Kyle Chadha Sep 22 '15 at 18:23
  • it is better to store the old logs on local variables rather on global ones, this answer shows that way https://stackoverflow.com/questions/6455631/listening-console-log – Pablo Pazos Jul 25 '18 at 00:16
9

More Succint Way:

// this method will proxy your custom method with the original one
function proxy(context, method, message) { 
  return function() {
    method.apply(context, [message].concat(Array.prototype.slice.apply(arguments)))
  }
}

// let's do the actual proxying over originals
console.log = proxy(console, console.log, 'Log:')
console.error = proxy(console, console.error, 'Error:')
console.warn = proxy(console, console.warn, 'Warning:')

// let's test
console.log('im from console.log', 1, 2, 3);
console.error('im from console.error', 1, 2, 3);
console.warn('im from console.warn', 1, 2, 3);
Inanc Gumus
  • 25,195
  • 9
  • 85
  • 101
9

I know it's an old post but it can be useful anyway as others solution are not compatible with older browsers.

You can redefine the behavior of each function of the console (and for all browsers) like this:

// define a new console
var console = (function(oldCons){
    return {
        log: function(text){
            oldCons.log(text);
            // Your code
        },
        info: function (text) {
            oldCons.info(text);
            // Your code
        },
        warn: function (text) {
            oldCons.warn(text);
            // Your code
        },
        error: function (text) {
            oldCons.error(text);
            // Your code
        }
    };
}(window.console));

//Then redefine the old console
window.console = console;
Ludovic Feltz
  • 11,416
  • 4
  • 47
  • 63
1

I needed to debug console output on mobile devices so I built this drop-in library to capture console output and category and dump it to the page. Check the source code, it's quite straightforward.

https://github.com/samsonradu/Consolify

Samson
  • 2,801
  • 7
  • 37
  • 55
0

In the same function that you are using to do console.log(), simply post the same message to a web service that you are recording the logs on.

Joshua
  • 3,615
  • 1
  • 26
  • 32
  • Not option, it is to expensive, what if page have a 100 errers and warnings, should I make for each ajax request, I don't think so – Milan Jaric Nov 03 '11 at 18:44
  • 1
    @MilanJaric, your objection makes no sense. If you're capturing the console output, you'd still be making 100 AJAX calls. – Joe White Nov 03 '11 at 19:02
  • no I'm keeping it in one variable (object) and when user is about to leave page it will post data to back end. – Milan Jaric Nov 03 '11 at 19:15
  • 1
    Milan - If you want to cut down on number of AJAX requests, you could push console messages to an array and just send the array. However generally when the user leaves the page, JS functions will stop, so it won't post the data. – Joshua Nov 04 '11 at 13:49
0

You're going about this backwards. Instead of intercepting when an error is logged, trigger an event as part of the error handling mechanism and log it as one of the event listeners:

try
{
  //might throw an exception
  foo();
}
catch (e)
{
  $(document).trigger('customerror', e);
}

function customErrorHandler(event, ex)
{
  console.error(ex)
}
function customErrorHandler2(event, ex)
{
  $.post(url, ex);
}

this code uses jQuery and is oversimplified strictly for use as an example.

zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • jQuery is not option, what if it fails to load :) – Milan Jaric Nov 03 '11 at 18:41
  • 2
    @MilanJaric, then what if your error-handling code fails to load? What if your AJAX-log-to-database call fails? – Joe White Nov 03 '11 at 19:03
  • it will not if it is in with page inside `` – Milan Jaric Nov 03 '11 at 19:17
  • @MilanJaric, you can trigger custom events without using jQuery. I'm using jQuery only because it's a simple way of showing an example. The code to trigger custom events without jQuery is much more complex and would take longer to write than the minute i spent answering your question. – zzzzBov Nov 03 '11 at 19:56
  • Don't be mad at me, but you example is really not something I'm trying to find, even if we put aside jquery, but be sure I REALLY appreciate you time to make this answer. Actually anyone. That is the reason why I never degrade answers from anyone! Thanks allot. – Milan Jaric Nov 03 '11 at 20:05
  • 1
    But not all errors can be trapped. ERR_BLOCKED_BY_CLIENT is one example. Try trapping that. – Bangkokian Sep 17 '15 at 08:33