How to log errors coming from React components

December 24, 2015 React JavaScript error reporting Airbrake

Here’s a problem we had with React: prop type validation only emits a console message. Besides, React isolates errors within components that they have happened in. This means you cannot just put try...catch around any block of code to log errors. window.onerror does not work, either. And nobody has time to keep an eye on all console messages.

The solution we found is to hook console.error and intercept errors there. This will not work in production. (If it does, you are doing the build wrong.) But collecting errors will help with QA a lot.

First, you need a way to hook into the console.

// Replace console[messageType]
// with    handler(messageType, oldHandler, ...arguments)
// where oldHandler is the original method so you can chain
var hookConsole = function(messageType, handler) {
  if (typeof console === 'undefined') return;
  var oldHandler = console[messageType];

  console[messageType] = function() {
    var params = [].slice.call(arguments);
    params.unshift(oldHandler);
    params.unshift(messageType);
    return handler.apply(this, params);
  }
}

It’s useful to have this method factored out. We have different handlers for tests and for staging. It can also be used to filter out annoyingly useless log messages.

Then, you send the error into one of the many error aggregation services: Airbrake, Sentry, etc.

Here’s an example for Airbrake:

var installAirbrakeErrorReporter = function(airbrake) {
  var logWithAirbrake = function(errorType, oldHandler) {
    var params = [].slice.call(arguments, 2);
    var message = params.join(' ');
    airbrake.notify({error: {message: message}});
    return oldHandler && oldHandler.apply(this, params);
  }

  patchConsole('warn', logWithAirbrake);
  patchConsole('error', logWithAirbrake);
}

With this solution we could finally make use of propType validation, and ensure proper component cohesion inside our app.

Buy Me a Coffee at ko-fi.com