HiveBrain v1.2.0
Get Started
← Back to all entries
debugjavascriptMinor

Exceptions for control flow

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
exceptionsflowforcontrol

Problem

I just wrote the following javascript (jQeury loaded):

var valid, ui;

try {
    $.each(this._cache, function() {
        $.each(this, function() {
            $.each(this, function() {
                if (this.label.toLowerCase() === valueLowerCase) {
                    valid = true;
                    ui = {item: $.extend({}, this) };
                    throw 'Control flow throw, please rethrow if accidently caught';
                }
            });
        });
    });
} catch(e) {}


My coworker suggested I rewrite this as follows:

var valid, ui;

$.each(this._cache, function() {
    $.each(this, function() {
        $.each(this, function() {
            if (this.label.toLowerCase() === valueLowerCase) {
                valid = true;
                ui = {item: $.extend({}, this) };
            }
            return !valid;
        });
        return !valid;
    });
    return !valid;
});


I think this is a valid case of using exceptions as control flow. Which way is the correct way to do this?

Solution

As Jef Vanzella mentioned, exceptions are for unexpected bad things, not for jumping out of control flow. Hence the second option is better, but it is still substandard code.

Instead of using this, you should have a meaningful parameter name in your function declaration.

Also, you could simply return the falsey !ui instead of !valid.

Finally, not many people know that returning false stops the iteration, that deserves a comment.

Now imagine that your data structure was Cache -> Orders -> Shipments -> Items then you could write:

var ui;

//Returning false to each() will stop the iteration
$.each(this._cache, function( order ) {
    $.each(order, function( shipment ) {
        $.each(shipment, function( item) {
            if (item.label.toLowerCase() === valueLowerCase) {
                ui = {item: $.extend({}, this) };
            }
            return !ui ;
        });
        return !ui ;
    });
    return !ui ;
});

Code Snippets

var ui;

//Returning false to each() will stop the iteration
$.each(this._cache, function( order ) {
    $.each(order, function( shipment ) {
        $.each(shipment, function( item) {
            if (item.label.toLowerCase() === valueLowerCase) {
                ui = {item: $.extend({}, this) };
            }
            return !ui ;
        });
        return !ui ;
    });
    return !ui ;
});

Context

StackExchange Code Review Q#25432, answer score: 3

Revisions (0)

No revisions yet.