Rescue front-end errors with a Rack middleware

Developing a front-end Web application implementing a backend API is a great way to separate business logic from user experience.

Front-end MVC frameworks like Ember.js, AngularJS and [insert latest buzzing JS framework here], have changed how we architecture our applications. They take full power of the otherwise idle client device to provide a richer user experience and potentialy reduce your server’s workload.

One thing lacking with this new paradigm is a reliable way to get detailed information on how your users interact with your application. With the classic backend rendered templates type applications, errors are raised and logged on the backend. Now, the whole experience is mostly asynchronous; errors are raised on the client device and thrown to the browser console without you knowing. You get less insights out of the box; less information about your users’ frustrations. I wrote the frontend_rescue gem to solve this pain.

FrontendRescue

frontend_rescue provides a backend endpoint as a rack middleware for your front-end JavaScript applications to send errors to when they’re caught. By default, these front-end stack traces will be displayed alongside your backend output, but you can override this behaviour if need be. For example, you can integrate your front-end stack traces to your backend analytics tools.

Usage

I use frontend_rescue to log errors sent from my Ember.js application to NewRelic. For some reason I don’t care about errors raised by Googlebot.

Rails

You can pass in a block to do whatever you want with the error.

1
2
3
4
5
6
7
8
Rails.application.configure do config.middleware.use FrontendRescue::Middleware, paths: ['/frontend-error'], exclude_user_agent: /Googlebot/, status_code: 200 do |error| NewRelic::Agent.notice_error(error) end end

See README for more configuration options.

Ember.js

Ember.js makes it super easy to catch all errors and report them to our endpoint.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Ember.onerror = function(error) { Ember.$.ajax('/frontend-error', { type: 'POST', data: { name: 'Ember App', user_agent: navigator.userAgent, message: error.message, stack: error.stack } }); if (App.get('env.name') === 'development') { return console.log("Caught and sent to server:\n " + error.stack); } };

Visit the Github repository for the details.