1

I've been struggling with error handling in durandal.

I've found it is desirable to to place much much of the logic for rendering views etc in the activate function.

This was working well untill I noticed a few programming errors caused the whole app to fall over very silently. i.e. Nothing written to the console, no trapped error, the app just hangs on the activate function.

Is this expected behaviour. Should I be moving the application logic for my app elsewhere?

The actual code is a little awkward and a lot is wrapped in jquery promises etc.

To prove what I was seeing I wrote the following:

    public activate(stationId: string): void {
        throw "Error in detail activate";
    }

Which wrote nothing to the console and raised no other apparent error, other than hanging the application.

The immediate thing that occurs:

    public activate(stationId: string): void {
        setTimeout(function() { 
            throw "Error in detail activate";
        }, 0);
    }

In this situation the activate function progressed but unfortunately it was not possilbe to track this error either?

I'm concerned that I need to find a way of performing applicaiton logic at activate point, but it would be useful if these errors were not simply swallowed.

Done a little more investigation and digging into Durandal.

The error still disappears. Despite obvious attempts by Durandal to log the error. I have been looking in activator.js activate function:

try {
    result = invoke(newItem, 'activate', activationData);
} catch (error) {
    system.error(error);
    callback(false);
    return;
}

Essentially the catch condition is run and system error is called. The result seems to disappear into knockout bindings etc. Is there anyway to make this error more visible. For now I'm stuck with putting a breakpoint on the activator.js activate function.

Am using v2.0.1 of durandal.

Captain John
  • 1,859
  • 2
  • 16
  • 30
  • `activate` is not the place for logic associated with rendering views since the view is rendered at that point. It is the place for preparing data for use in the view, among other things. You should look to `attached` and `compositionComplete` for view rendering. The signature of `attached` and `compositionComplete` provide access to the view in their arguments. I wonder if you should move your code to either one of those two methods. –  Apr 23 '14 at 21:18

1 Answers1

0

Enable system.debug. This will let durandal log those errors to the console.

E.g. in your initial boot module

define(['durandal/app', 'durandal/viewLocator', 
    'durandal/system', 'plugins/router', 'services/logger'], boot);

function boot (app, viewLocator, system, router, logger) {

    // Enable debug message to show in the console 
    system.debug(true);

    // and so on
}

This works for canActivate(), it also works in activate() when you use setTimeout(). It doesn't appear to work in activate() without the setTimeout() though.

Debugging:

Performing the logic in canActivate() without a call to setTimeout will result in a stack trace that just contains internal methods from durandal system, router and jquery. You'll still have to poke around for the offending line.

Performing the logic via a call to setTimeout() however, will give you a stack trace that tells you exactly where the error occurred.

JamesT
  • 2,988
  • 23
  • 29
  • Ok! Hadn't thought to check the system.debug(true); setting. Sadly it is set :-( I am not seeing anything useful in the Console logging – Captain John Apr 23 '14 at 09:15
  • Which browser are you working in. I tested the above with Chrome and IE11. Also, your code looks like Typescript, which in fairness I didn't test so there may be something there. – JamesT Apr 23 '14 at 09:43
  • Yes well spotted It's typescript. I doubt that's the issue, I'm using IE11, I'll give Chrome a quick go. One thing which may be muddying the waters, I'm getting errors off a Web essentials plugin which I'd like to remove. – Captain John Apr 23 '14 at 09:55