Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swallowing errors in templates #555

Closed
danheberden opened this issue Mar 21, 2014 · 6 comments
Closed

Swallowing errors in templates #555

danheberden opened this issue Mar 21, 2014 · 6 comments

Comments

@danheberden
Copy link

When a syntax error exists in a handlebars template, no meaningful error is exposed. I was able to get this distilled to the following:

  • Fresh pull of EAK
  • add this to the application.hbs file
{{#if}}
  will error
{{/else}}

Obviously incorrect syntax, but we should get some sort of "hey, bozo, you goofed up in your application.hbs template" or at least a better stack trace than:

  • Notice the error in console
Uncaught TypeError: Cannot read property 'name' of undefined - ember.js:35015
updatePaths - ember.js:35015
Ember.Router.Ember.Object.extend.intermediateTransitionTo - ember.js:34522
(anonymous function) - ember.js:34919
forEachRouteAbove - ember.js:34869
defaultActionHandlers.loading - ember.js:34915
triggerEvent - ember.js:34983
trigger - ember.js:34116
Transition.trigger - ember.js:33952
Ember.Router.Ember.Object.extend._fireLoadingEvent - ember.js:34750
DeferredActionQueues.flush - ember.js:5893
Backburner.end - ember.js:5984
Backburner.run - ember.js:6023
Ember.run - ember.js:6426
runInitialize - ember.js:39637
fire - jquery.js:1037
self.fireWith - jquery.js:1148
jQuery.extend.ready - jquery.js:433
completed - jquery.js:103

This at least shows an error. I've been getting situations lately when there is an error in my view and the app just simple doesn't render it. Under the Ember Dev Tools promises section i get:

Ember Inspector ($E):  TypeError: Cannot read property 'container' of undefined
    at routeHasBeenDefined (http://localhost:8000/vendor/ember/ember.js:34954:25)
    at defaultActionHandlers.error (http://localhost:8000/vendor/ember/ember.js:34899:11)
    at Object.triggerEvent (http://localhost:8000/vendor/ember/ember.js:34983:33)
    at trigger (http://localhost:8000/vendor/ember/ember.js:34116:16)
    at Object.Transition.trigger (http://localhost:8000/vendor/ember/ember.js:33952:9)
    at finalizeTransition (http://localhost:8000/vendor/ember/ember.js:33273:22)
    at http://localhost:8000/vendor/ember/ember.js:32781:22
    at http://localhost:8000/vendor/ember/ember.js:33000:19
    at invokeResolver (http://localhost:8000/vendor/ember/ember.js:9386:9)
    at new Promise (http://localhost:8000/vendor/ember/ember.js:9372:9) 
@stefanpenner
Copy link
Owner

Pause on all exceptions is your friend. Beyond that we can also rethrow the error

Best of both worlds

@danheberden
Copy link
Author

It's more informative in that "hey, handlebars got upset" but

if(mustache.id.original !== close.path.original) {
  throw new Exception(mustache.id.original + " doesn't match " + close.path.original);
}

doesn't offer too many clues as to what's going on :/

@stefanpenner
Copy link
Owner

@danheberden i don't think the later is really an EAK thing... Although the former we can likely improve :)

@herom
Copy link

herom commented Mar 27, 2014

I see the same error in my application, but I can't track it down to some template error since I also get it if I test it with the following application.hbs file:

<h1>Hello World!</h1>

I created my own CustomResolver which looks like this:

import JJAbramsResolver from 'ember/resolver';
import Logger from 'appkit/utils/logging/console-logger';
import ApplicationContainer from 'appkit/utils/application/container';

var AppkitResolver = JJAbramsResolver['default'];

var CustomResolver = AppkitResolver.extend({
  templateManager: null,

  templateQueue: Ember.A([]),

  templateManagerDidChange: function () {
    Logger.log('TemplateManager was set!');
  }.observes('templateManager'),

  populateTemplateManager: function () {
    var templateManager = this.get('templateManager');

    if(!templateManager && ApplicationContainer.lookup) {
      templateManager = ApplicationContainer.lookup('template_manager:app');

      if(templateManager) {
        this.set('templateManager', templateManager);
      }
    }

    return templateManager;
  },

  /**
   * Overrides the default `resolveTemplate` method of the `AppkitResolver` (which refers to `AppkitResolver#resolveOther()`)
   * and implements the `TemplateManager` for retrieving the precompiled
   * Handlebars templates from the server.
   *
   * @method resolveTemplate
   * @param {Object}    parsedName
   * @returns {Object}  The template from the `Ember.TEMPLATES` template cache.
   */
  resolveTemplate: function (parsedName) {
    // if however the parsedName.type is not 'template' exit now
    if (parsedName.type !== 'template') {
      Logger.error('CustomResolver:: parsedName () is not template type'.fmt(parsedName.fullName));
      return undefined;
    }

    var templateManager = this.populateTemplateManager();

    // this whole if/else block never gets called
    if(!templateManager) {
      this.get('templateQueue').pushObject(parsedName);
      Logger.log('CustomResolver:: Got request for %@ but TemplateManager is still not available....'.fmt(parsedName.name));
      return undefined;
    } else if (this.get('templateQueue.length') > 0) {
      Logger.debug('CustomResolver:: got something in templateQueue!');
      Logger.log(this.get('templateQueue'));
    }

    Logger.debug('CustomResolver:: Fetching Template (%@) via own implementation!'.fmt(parsedName.name));

    var templateName = parsedName.fullNameWithoutType.replace(/\./g, "/");

    if (templateName.indexOf("/") < 0 && templateName !== 'application') {
      templateName = this.templateManager.fetchTemplate(templateName + "/root", templateName);
    } else {
      templateName = this.templateManager.fetchTemplate(templateName);
    }

    return Ember.TEMPLATES[templateName];
  }
});

export default CustomResolver;

and I add it to my Application like:

import CustomResolver from 'appkit/utils/resolver/custom';

var App = Ember.Applicaiton.create({
  modulePrefix: 'appkit',
  Resolver: CustomResolver
});

Alas I'm logging all resolveTemplate attempts, I never see a request to load/resolve the application template, only the request for the loading template is logged...

@herom
Copy link

herom commented Mar 27, 2014

As I traced down the problem (first I didn't recognize your comment on using pause on all exceptions in dev tools @stefanpenner ) I could see that my problem(s) is/are not related to the template file but are several problems with my code where the messages of the errors are not shown but swallowed.

I saw that the messages from Ember.assert are swallowed so that these assertions are never shown in the console and therefore leaves the developer in a desperate situation. Only after I checked to pause on all exceptions I came to the lines of code where the Ember.assertion gets called and I could dump the content of the desc parameter to get the error description...

Is there an internal error handler swallowing the assertions and errors thrown by Ember so that this could fail silently and only prints the StackTrace when the error could not be caught, which seems is at the code line ember.js: 35015 @stefanpenner? (sorry for pingin' two times 😃 )

@fsmanuel
Copy link
Collaborator

@danheberden your example in application.hbs is a ember bug.
the problem is that there is no parent route that could handle the error:

// Line 35015
set(appController, 'currentRouteName', infos[infos.length - 1].name);

infos[infos.length - 1] will always be undefined if there is an error in application.hbs. you should open an issue on ember.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants