Blog Home » TODO: Error Handling in EmberJS

TODO: Error Handling in EmberJS

By Nick Pelton

Welcome to the next installment of the TODO Error Handling series from TrackJS. We’ve looked at the TODOMVC.com example applications and wiring them up for better error handling with TrackJS. In other posts, we’ve covered:

EmberJS is an open-source JavaScript application framework, self described as “A framework for creating ambitious web applications”. In this integration, we’ll be using the EmberJS TODO app from TODOMVC.com as our example application.

EmberJS Error Handling

EmberJS has some really great debugging tools built right in. But most of the tools are meant for development debugging and not for production use. It also has a phenomenal Chrome debugger extension called Ember Inspector, which provides some great visibility during development, The EmberJS guide section covers them in detail. In that guide, they also cover using their Ember.onerror callback to handle errors.

If an error occurs within the EmberJS application it will trigger the Ember.onerror method. By default this method is null but you can easily redefine it:


Ember.onerror = function(error){

  // Do something with the error here

  // Optional: pass error to Embers.Logger
  Ember.Logger.assert(false, error);
};

In the guide they also recommend using Ember.onerror for production logging, making it an ideal place to integrate TrackJS.

Integrating TrackJS

Extending basic error handling of EmberJS with TrackJS allows you to track and trend how your application breaks. Basic integration with EmberJS is as easy as copying your TrackJS tracker script snippet into your application. Simply signup for a TrackJS account and paste the script into your markup.

Basic Error Integration

TrackJS enhances EmberJS error handling, greatly increasing the chance of getting a stack trace. Let’s create an error to see what kind of data TrackJS captures for us out of the box. Start by simply using the App, create a few TODOs, edit one, and delete one. Once you feel good about your list – open the console and enter console.error("Something broke!").

Open TrackJS and you’ll see the error was captured along with all the user interactions and data. For user inputs we provide the user action, element markup snapshot, and a value interpretation. We never send input data to TrackJS, we instead parse the HTML and regex the values, then filter out the value info before we collect it. This is a secure way to give you insight to the type of input without exposing private data. If you’re using the non-minified version of Ember.js in development it will automatically log library version numbers in the telemetry timeline, but you can see TrackJS already captures that information in the “Libraries” section.

Ember Telemetry Error

Customized Error Integration

You already get great coverage with a basic installation of TrackJS, but if you want access to private data and methods within the application we need a deeper integration – let’s integrate TrackJS directly with the Ember.onerror method.


// Log any Emberjs errors to TrackJS
Ember.onerror = function(error){

  if(window.trackJs) {
    window.trackJs.track(error);
  }

  // Optional pass error through to embers error logger
  Ember.Logger.assert(false, error);
};

// Log Ember Promise Errors
Ember.RSVP.on("error", function(error) {

  if(window.trackJs) {
    window.trackJs.track(error);
  }

  // Optional pass error through to embers error logger
  Ember.Logger.assert(false, error);
});

Now if an error occurs within the Ember application it will be caught and passed to TrackJS to be logged. We also added an on("error") handler to Ember.RSVP to catch any promise errors. Since TrackJS is within the scope of the application it’s easy to add additional information to the error logs. We can also pass the error object back to the Ember.Logger, an optional step that will ensure the error is visible in the console.

Example Errors

Now for the fun stuff, let’s break our EmberJS application by causing an error. Open up todo_controller.js and add an undefined(); function within the actions.removeTodo method.


// In controllers/todo_controller...
removeTodo: function () {
  var todo = this.get("model");

  // Oops, we broke it
  undef();

  todo.deleteRecord();

  todo.get("store").commit();
}

Now refresh your browser, add a few todos and then try to remove one-todos cannot be removed, as expected, and an error is triggered. Open TrackJS and navigate to the new error, you’ll see that we’ve captured the stack trace as well as some additional context.

Ember Advanced Error

Application Specific Information

Getting an error message, stacktrace plus app telemetry adds so much more insight into your applications errors. With some simple TrackJS config options you can add application specific context for your own reference when reviewing application errors. You can easily add these parameters in the TrackJS config object on initialization.


TrackJS.install({
  version:    "VERSION_FROM_SERVER",
  sessionId:  "SESSIONID_FROM_SERVER",
  userId:     "USERID_FROM_SERVER",
  application:"APP_SLUG_FROM_TRACKJS",
  token:      "YOUR_TOKEN_FROM_TRACKJS"
});

If you cause the same undefined error you’ll see the additional data in the “Application Information” box. You can also filter errors by UserID directly from this box, or by navigating to the “Users” tab once you’ve logged UserIds. “Applications” adds the ability to segment all error data using a simple application slug in your config, simply add your app in the TrackJS Applications page and add the slug to your config.

Custom Logging

The Telemetry Timeline is super helpful for replicating errors and it can speak volumes when you add additional log info. For example, we can log applications events, initializations, timestamps, and more. This data will be captured in the timeline. We’ve added some console.log() calls during initializations and when specific methods fire–building your own black-box of events in case an error occurs. EmberJS also provides some config options to add additional logging we can enable. We also enhanced the Ember.onerror callback with some additional route information :


// Log any Emberjs errors to TrackJS
Ember.onerror = function(error){

  if(window.trackJs) {
     // Add some additional context (optional)
     window.trackJs.console.log("currentRouteName: "+window.Todos.__container__.lookup("controller:application").get("currentRouteName"));
     window.trackJs.console.log("currentPath: "+window.Todos.__container__.lookup("controller:application").get("currentPath"));
     window.trackJs.track(error);
  }

  // Optional pass error through to embers error logger
  Ember.Logger.assert(false, error);

};

Now if you trigger an error you’ll see the logged events in the telemetry timeline as well as the additional application context we added in the Ember.onerror callback. This is the power of TrackJS, not we can completely replicate the state the application was in during an exception; and fix it.

Ember Custom Error

Custom Events

Want to track your own Telemetry events? At any time you want to capture the latest network, console, and user interactions simply call trackJs.track() method. In this case we simply want to see what was going on right before the user edits a todo. Simply add trackJs.track("custom event capture"); at the point you want to capture TrackJS history. This can be incredibly handy when trying to track down a UI or logic error that doesn’t actually cause an exception.


Another JavaScript framework protected by TrackJS. We hope you learned a bit about error handling in EmberJS and how easy it is to get started with error handling. If you haven’t already, grab a free 14-day trial and let us help you start finding and fixing bugs in your EmberJS applications!

Nick Pelton
Nick Pelton