Capturing and reporting errors in production


#1

I have recently set up an errbit (http://errbit.github.io/errbit/) install that works great for server-side errors but the client-side errors aren’t very useful because they only return the error text with no context, for example:

Uncaught Error: Something you did caused a view to re-render after it rendered but before it was inserted into the DOM.

With this there’s no way to tell where in the app it occurred or what might have caused the error.

How are people capturing and reporting client-side errors in their production apps? Is there a better way of capturing Ember errors along with their stack trace?


#2

From http://slid.es/istefo/emberfest:

MAINTAINING TRACK ERRORS

Ember.onerror = function(error) {
    Ember.$.ajax('/report-error', 'POST', {
        stack: error.stack,
        otherInformation: 'whatever app state you want to provide'
    });
} 

Or use services like Errorception, ExceptionHub, Debuggify, Airbrake…

EDIT: also http://rollbar.com/

Hope this helps? Did not test it for myself…


#3

Yes, Ember.onerror is what you want, but be aware that there are some open issues that will prevent certain exceptions from being reported there. See https://github.com/emberjs/ember.js/issues/3401

To trap wider range of potential errors, I do the following (report_error is my function that takes an Exception and deals with logging and reporting it):

 // Trap exceptions from within Ember run loop
 Ember.onerror = report_error;

 // Trap unhandled RSVP promise failures
 Ember.RSVP.configure('onerror', report_error);

 // Trap unhandled failures during routing
 App.ApplicationRoute = Ember.Route.extend({
      actions: { error: report_error }
 });

// Safety net to report any untrapped exceptions on browsers
// that respect window.onerror.  Currently, failures from within 
// Backburner callbacks will end up here. This is inferior to the 
// other handlers because the stack trace is missing by the 
// time the exception gets here.
window.onerror = report_error;

#4

Thanks for the help guys. I have ended up switching to BugSense for JS errors as they seemed to have the best support for custom error notification.

I’ll post an update here once I’ve determined how successful the switch was.


#5

I spoke too soon, still struggling to get any meaningful info from BugSense.

I think I’ll resort to building my own rails endpoint and submitting errors to that manually.


#6

This is my first, quick pass at custom error reporting. It uses Airbrake and is formatted for display in Errbit (using the Airbrake interface you might be able to get better formatting using different options).

Note: Don’t use this in production as-is, it has a number of bugs and possibly some unwanted behaviour. If anyone builds a better solution, please share!

application.js:

function report_error(error) {
  var extra_info = {};

  try {
    if (App.Auth.get('signedIn')) {
      user = App.Auth.get('user');
      extra_info['user_id'] = user.get('id');
      extra_info['user_username'] = user.get('username');
      extra_info['user_email'] = user.get('email');
    }
  } catch(err) { }

  Ember.$.ajax('/errors', { type:'POST', data: {
    name: error.name,
    message: error.message,
    stack: error.stack,
    url: document.location.href,
    extra_info: extra_info
  }});
};

if (RAILS_ENV != 'development') {
  // Trap exceptions from within Ember run loop
  Ember.onerror = report_error;

  // Trap unhandled RSVP promise failures
  Ember.RSVP.configure('onerror', report_error);
}

errors_controller.rb:

def create
  extra_info = params[:extra_info]

  user = {}
  user['id'] = extra_info.delete('user_id')
  user['username'] = extra_info.delete('user_username')
  user['email'] = extra_info.delete('user_email')

  Airbrake.notify(
    error_class: params[:name],
    error_message: params[:message],
    url: params[:url],
    environment_name: Rails.env,
    user: user,
    backtrace: [],
    component: params[:stack].lines[1],
    cgi_data: { stack: params[:stack] }
  )

  render nothing: true, status: 200
end

#7

Sentry is also great: https://getsentry.com/ It’s open source, so you can host it yourself too.


#8

Sentry is working much better, thank you!

I set up my own instance on Heroku using https://github.com/fastmonkeys/sentry-on-heroku. One thing not mentioned is that you need to set the ALLOWED_HOSTS config in the sentry.conf.py file to avoid 500 errors.


#9

Hello @lookingsideways! I’m a front-end engineer in BugSense and I maintain the javascript plugin. As we’re currently doing a major refactor of our plugin and we loved to get your feedback on how was your experience using our plugin.

Please ping me at dimitris[ at ]bugsense.com


#10

Ember.RSVP.configure(‘onerror’, fn) is changed to Ember.RSVP.on(‘error’, fn)


#11

ember-cli-sentry and ember-cli-deploy-sentry seem to be the best addons for handling error reporting. Sentry really is pretty amazing. Lots of useful integrations too. Check the pull requests and issues, currently the addon doesn’t put in the applicationRoute actions: { error: handler, so you’ll definitely want make sure you add this to you applicationRoute’s error action:

    error(error) {
      // Trap unhandled failures during routing:
      // Should maybe be handled by the sentry addon, but is not as of now:
      // https://github.com/damiencaselli/ember-cli-sentry/issues/105
      this.get('logr').captureException(error);