My standard workflow for debugging

I’ll admit that I have a lot of experience with things not going well in Ember.
Over time I’ve started to get a general workflow in place that I’d like to share.
When I have to debug it’s commonly performed from two points of view. Either the page didn’t render at all due to a javascript error,
or the page rendered, just not in the way that I was expecting. From there I find myself following the flow in the chart below.

<sodipodi:namedview pagecolor=”#ffffff” bordercolor=”#666666″ borderopacity=”1″ objecttolerance=”10″ gridtolerance=”10″ guidetolerance=”10″ inkscape:pageopacity=”0″ inkscape:pageshadow=”2″ inkscape:window-width=”2462″ inkscape:window-height=”1328″ id=”namedview4244″ showgrid=”false” inkscape:zoom=”1.1972936″ inkscape:cx=”387.8658″ inkscape:cy=”1045.9024″ inkscape:window-x=”0″ inkscape:window-y=”0″ inkscape:window-maximized=”0″ inkscape:current-layer=”g3832″ inkscape:snap-global=”true” inkscape:snap-midpoints=”true” inkscape:snap-bbox=”true” inkscape:object-nodes=”true” inkscape:bbox-nodes=”true”/> Produced by OmniGraffle 6.5.2 <dc:date>2016-07-29 19:32:49 +0000</dc:date> <rdf:RDF><cc:Work rdf:about=””><dc:format>image/svg+xml</dc:format><dc:type rdf:resource=”http://purl.org/dc/dcmitype/StillImage”/><dc:title/></cc:Work></rdf:RDF> Canvas 1 Layer 1 <xlink:use xlink:href=”#id1_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id168_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id19_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id23_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id163_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id47_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id59_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id3_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id25_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id31_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id68_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id34_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id96_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id98_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id110_Graphic” filter=”url(#Shadow)”/> <xlink:use xlink:href=”#id173_Graphic” filter=”url(#Shadow)”/> I don’t see what I was expecting There was a javascript error Maybe the routes aren’t running correctly . LOG_TRANSITIONS_INTERNAL: true Check the rendered state of the template using the inspector W as there a javascript error? Not really Y es Did the page render at all? – Reload and see if the transition to the page fi nished successfully. If a transition failed go debug from there – Make sure any ajax requests completed successfully Are the values in the template/ components what you expected? Obvs No How is that particular value supposed to be set? – Check dependent keys – Set a breakpoint and check if the observer is fi ring as intended – Make sure you’ve added .on(‘init’) if needed Observer – Check dependent keys – Make sure the property isn’t getting overwritten Computed Property – Set a breakpoint and make sure the helper is recomputing as needed Helper – Make sure the value isn’t getting set from somewhere else T emporarily add an observer that watches the value and set a breakpoint there Binding – Set a breakpoint and check that the action is fi ring as intended – For closure actions make sure params are curried correctly Action – Make sure the hook is fi ring, especially if the problem is occurring after a value change or re- render – If the rerender is from a route transition, ember might reuse an instance of a given component and not call the Init() hook every time. – Make sure to call this._super(…arguments) Component Lifecycle Hook Does the CP depend on something async? – DS.hasMany(‘foo’, {async: true}) – PromiseProxy , PromiseArray , etc. Make sure the CP is still valid when the async dependency is in an unfulfi lled state -If there’ s a consistent problem in a runloop use Ember.run.backburner.DEBUG = true – If using chrome make sure the ‘async’ check box on the inspector is enabled – If the browser stack trace isn’t useful take a look the error s ‘stack’ property – Check server responses – Set a breakpoint and check if the observer is fi ring as intended – Make sure you’ve added .on(‘init’) if needed Ember Data Model

A small companion guide

  • Start at the template. The template is the source of truth for what goes on the screen, and Ember’s handy inspector makes it
    quick to confirm the state of all those bound values. If the page rendered incorrectly it means a bound value somewhere isn’t what I was expecting.
    From there I go to each incorrect value and try to determine how it was set, essentially recursing back through the flowchart.

  • Blank screens and no error? Start logging. In some apps the way I’ve (poorly) set up my routes and their error handling will lead to a route swallowing
    an error during a transition. If I come across a blank page with no error I’ll normally set LOG_TRANSITIONS_INTERNAL: true like the debugging guide
    demonstrates. Then tracking down the failed route hook is a snap.

  • Check computed property dependent keys I’ve shot myself in the foot countless times from typos or plain mistakes in computed property keys. If I write a property whose keys don’t
    correspond to the get() calls inside, I try to write a comment saying why.

  • I <3 developer tools I couldn’t get through my working day if I didn’t have the Chrome developer tools. Half of the items on my flowchart involve setting a breakpoint somewhere
    in my app’s source code or in the ember source code. I often find myself setting a breakpoint at an obvious place, then navigating up the stack and setting more breakpoints closer to
    what I think is the source of the problem.

  • Use error.stack When the browser pauses on an Ember error, there are many cases where the browser stack trace at that moment won’t be very useful. In that case, I check the thrown
    error’s stack property. It often has a more informative list of places for me to check.

  • Debug two-way bindings with observers Sometimes I get plain stuck trying to figure out how a value is being changed in a component. Observers to the rescue! Here’s a quick example:

Ember.Component.extend({
  heisenValue: "foo",

  // If heisenValue changes for any reason, the observer will fire synchronously
  // and show me where the change is coming from.
  forDebug: Ember.observer('heisenValue', function() {
    debugger;
  })
});
  • Check the server response If my Ember Data models aren’t showing the right information I’ll always take a quick look at the network response
    to make sure the data is what I’d expect before diving in further on the client side. It’s saved me a ton of time, especially when working on a new feature.

Take heart!

Debugging can be frustrating, but I’ve found having a consistent set of steps has made finding run of the mill problems much less taxing.

technology logo

Get a Free Consultation

Your Free Consultation will be packed full of discussions, brainstorming, and hopefully, excitement. The meeting is designed to help uncover your challenges, define your needs, and outline possible solutions so you can make decisions that will lead to the business outcomes you desire.

Free Webinar & Guide

Digital Tranformation
A simple guide to uncover the potential impact digital transformation can have on your organization