Horrendous bug!

I created a custom element as follows

import { autoinject, bindable, bindingMode } from "aurelia-framework";

@autoinject
export class SearchBox {
  @bindable public collection;
  @bindable({ defaultBindingMode: bindingMode.twoWay }) public value;
  @bindable public optionLabel = "";

  constructor(private readonly el: Element) { }

  public valueChanged(newValue, oldValue) {
    if (newValue === this.optionLabel) {
      return;
    }

    if (newValue !== oldValue) {
      this.notify();
    }
  }

  private notify() {
    this.el.dispatchEvent(new CustomEvent("change", {
      bubbles: true,
      detail: {
        value: this.value
      }
    }));
  }
}
<template>
  <div class="input-group">
      <div class="input-group-append">
          <i class="input-group-text fas fa-search"></i>
        </div>
    <select class="custom-select" value.bind="value">
      <option if.bind="optionLabel !='">${optionLabel}</option>
      <option repeat.for="item of collection" model.bind="item">${item.name}</option>
    </select>
  </div>
</template>

The bug is in the line
if.bind="optionLabel != '" - i.e. it is missing the closing quote - it should be
if.bind="optionLabel != ''"

Obviously it should have been written simply as if.bind="optionLabel"

So the problem is that using webpack and the new aurelia-cli bundler the code compiles fine. However, at run-time, the application hangs, and gives no warning messages at all.
It was only after installing Firefox that I could see that I could see in the console that it wasn’t loading search-box

[HMR] connected client.js:92
DEBUG [aurelia] Configured plugin aurelia-dialog. aurelia-logging-console:20:6
DEBUG [aurelia] Loading plugin aurelia-validation. aurelia-logging-console:20:6
DEBUG [aurelia] Configured plugin aurelia-validation. aurelia-logging-console:20:6
DEBUG [aurelia] Loading plugin bcx-aurelia-reorderable-repeat. aurelia-logging-console:20:6
DEBUG [aurelia] Configured plugin bcx-aurelia-reorderable-repeat. aurelia-logging-console:20:6
DEBUG [aurelia] Loading plugin aurelia-animator-css. aurelia-logging-console:20:6
DEBUG [aurelia] Configured plugin aurelia-animator-css. aurelia-logging-console:20:6
DEBUG [aurelia] Loading plugin resources/index. aurelia-logging-console:20:6
DEBUG [aurelia] Configured plugin resources/index. aurelia-logging-console:20:6
DEBUG [aurelia] Loading plugin aurelia-testing. aurelia-logging-console:20:6
DEBUG [aurelia] Configured plugin aurelia-testing. aurelia-logging-console:20:6
DEBUG [templating] importing resources for resources/elements/loading-indicator 
Array []
aurelia-logging-console:20:6
DEBUG [templating] importing resources for resources/elements/status-bar.html 
Array []
aurelia-logging-console:20:6
DEBUG [templating] importing resources for resources/elements/search-box.html 
Array []
aurelia-logging-console:20:6
DEBUG [templating] importing resources for resources/elements/nav-menu.html 
Array []
aurelia-logging-console:20:6

I don’t make this kind of mistake very often - but it would oh so great if some kind of warning could be given!

1 Like

You’re absolutely correct, the parser should throw in this case. I’ve already fixed this and a few other issues in the vNext parser, so I’ll backport those asap. Apologies for the inconvenience!

3 Likes

That’s great - Thanks very much.

By the way is there a reason as to why (at least in Chrome), the debugger doesn’t record the pre-startup process in the console? I mean the trace as in the previous message.

I’m not sure what you mean. What are you expecting to see in the console? The regular debug logs e.g. “loading module such and such”?

HMR] connected client.js:92
DEBUG [aurelia] Configured plugin aurelia-dialog. aurelia-logging-console:20:6
DEBUG [aurelia] Loading plugin aurelia-validation. aurelia-logging-console:20:6
DEBUG [aurelia] Configured plugin aurelia-validation. aurelia-logging-console:20:clock6:
etc....

In Firefox you get get this log in the console until it can no longer show the importing resources …

In Chrome you just get

HMR] connected client.js:92

There is nothing to indicate where you should even start looking for the problem

That’s because it’s a pretty horrendous bug :wink:

Infinite loops are hard to troubleshoot and should never happen in a parser. I hadn’t spent enough time on the error scenarios back when i rewrote the parser for vCurrent, that’s how this one slipped through.

Ok - point taken.

I thought I was being a bit melodramatic calling it a “horrendous bug” :slight_smile:

In Firefox you get …
In Chrome you just get …

Did you check your Chrome Console filters? Maybe it’s just hiding DEBUG verbosity :slight_smile:

1 Like

@jeremyholt I’m working on it: https://github.com/aurelia/binding/pull/720
It may take some time because there are more ramifications at play here. In any case thanks for reporting, it reminded me that vCurrent binding needs to start profiting as well from work done on vNext.

I’m a bit confused by this bug. I thought if.bind would be used in conjunction with a variable not an expression requiring evaluation so would expect to see if.bind=“optionLabel” or similar. Presumably this is too subtle for the transpiler?

The problem wasn’t how if.bind works. It was that there was a typo in the expression, which the compiler doesn’t report, and instead goes into some kind of endless loop.

The problem was entirely of my making - bad eyesight in not spotting my typo sooner!

The bug is in the line
if.bind="optionLabel != '" - i.e. it is missing the closing quote - it should be
if.bind="optionLabel != ''"

of course it really should have been
if.bind="optionLabel"