A better alternative to try catch block? Pretty Please?

Discussion in 'Javascript' started by valued customer, Apr 1, 2004.

  1. Is there a more concise way to do something like the the
    desired code below?

    The gripe is with the try-catch syntax. It takes *way* too
    many lines of code to evaluate a conditional expression
    when zero or more parts of the conditional expression may
    trigger an error. In this case, the trigger is a call to
    a non-defined (null) object.

    In other words, how can you do a more simple 'try' statement
    that simply spits out true or false, depending on whether
    the 'tried' code threw an error or not?

    Defining a function don't seem to work because you
    can't pass the 'try' code as an argument. Extending the
    'Global' constructor is not an option, so now what?

    Any suggestions? TIA.


    /// desired code (YAAY!) :) --------------------------------

    if ( try(Meth.random) && try(Myth.random) && try(Math.random) )
    {
    /// do something
    }


    /// existing code (YUUK!) :( --------------------------------

    var bTmp;
    var bOkMeth;
    try{Meth.random;
    bTmp=true;}catch(e){bTmp=false;} bOkMeth = bTmp;

    var bOkMyth;
    try{Myth.random;
    bTmp=true;}catch(e){bTmp=false;}bOkMyth = bTmp;

    var bOkMath;
    try{Math.random;
    bTmp=true;}catch(e){bTmp=false;}bOkMath = bTmp;

    if (bOkMeth && bOkMyth && bOkMath)
    {
    /// do something here
    }
     
    valued customer, Apr 1, 2004
    #1
    1. Advertisements

  2. // Define outside a function
    var global = this;

    function isDefined( r ) {
    return( 'undefined' != typeof r );
    }
    ...
    ...
    if(( isDefined( global['Meth']) && Meth.random ) &&
    ( isDefined( global['Myth']) && Myth.random ) &&
    ( isDefined( global['Math']) && Math.random ))
    {
    // all exist
    }

    If random is a method, that should work fine. If it's a property that
    could evaluate to false[1], you'd have to use isDefined() on that, too.

    Is that better?

    Mike

    [1] Boolean false, null, "" (empty string), or 0. Best avoid undefined as
    a valid value.
     
    Michael Winter, Apr 1, 2004
    #2
    1. Advertisements

  3. Exeptions should be ... well, the exception. Using them as
    conditionals is misusing them.
    if you have more than expression that necessarily throws exceptions,
    you'll just have to endure. That should rarely be the case.

    What would Meth.random throw? Why not
    if ( (typeof Meth!="undefined" && Meth.random) &&
    (typeof Myth!="undefined" && Myth.random) &&
    (typeof Math!="undefined" && Math.random)) {
    // ...
    }
    (maybe test against "null" too, if needed)

    or, using window as a reference to the global object:
    if (window.Meth && Meth.random &&
    window.Myth && Myth.random &&
    window.Math && Math.random) {
    //...
    }
    Well, you don't need the temporary variable. Just assign
    directly to bO

    /L
     
    Lasse Reichstein Nielsen, Apr 2, 2004
    #3
  4. The gripe is with the try-catch syntax. It takes *way* too
    Well, that's one way to look at it, although that particular
    viewpoint may be sidestepping the issue here. So far, the
    suggestions (to paraphrase):

    1) start from a globally scoped variable that you know exists;
    2) make appropriate tests against 'null' and undefined; and
    3) you shouldn't have to do this sort of thing very much ...

    make sense I suppose, but do not really address the point ...

    /// here is concrete example ---------------------------------

    /// the user is allowed to supply oData in numerous different ways

    var oData;
    //oData = ['#ff0000','#00ff00','#0000ff']; // one way
    //oData = {stripe:'red white blue'}; // another
    //oData = {stripe:['pink', 'azure', 'mauve']}; // yet another
    //oData = {colors:{stripe:['ruby', 'topaz', 'gold']}}; // yet another

    var aryFavoriteColors;
    aryFavoriteColors =(oData.constructor == Array) ? oData
    :(oData.stripe.constructor == String) ? oD[...]split(/\s+/)
    :(oData.stripe.constructor == Array) ? oData.stripe
    :(oData.colors.constructor == Object &&
    oData.colors.stripe.constructor == Array) ? oData.colors.stripe
    : ['green', 'blue', 'white']
    ;

    try{ alert(aryFavoriteColors[0]); }catch(e){}
    try{ WScript.Echo(aryFavoriteColors[0]); }catch(e){}
    try{ Console.writeln(aryFavoriteColors[0]); }catch(e){}
    try{ response.write(aryFavoriteColors[0]) }catch(e){}

    // This script runs some of the time, and produces errors other times,
    // depending on which format of 'oData' the user ultimately submits.

    // To make it error-proof, you have to add a lot of try-catch stuff
    // (YUUK!!) Why can't I just say 'try one of these options, if *none*
    // of them works, don't give me any error messages or throws or popups.
    // Away of that! Just give me the default value ...
    // ['green','blue','white']

    The original request was for a more elegant way to construct a
    *conditional* ... the try-catch-throw debate is largely irrelevant.

    Given these circumstances ...

    1) The application is dealing with a large, heterogeneous and
    potentially complicated object heirarchy; (aka DOM; DHTML; XML)
    2) The exact structure of that heirarchy is potentially uknown
    until runtime (aka user can modify everything); AND
    3) The user has (or demands) the flexibility to define the semantics
    of the hierarchy according to their own personal preferences (aka
    mutliple ways to express the same thing).
    4) The application needs the flexibility to run in different contexts
    without laborious and bug-prone rewrites.

    .... It seems quite reasonable to expect someone would want to use
    conditionals in this way.

    By the way, another option, enclosing the conditional
    inside separate try block, just like with the last few lines
    in the example code
    above. Yes, that works (sorta), but again, you still have to
    segment the code
    into little 'try-catch' islands. When all you really want is
    to do a simple 'if' statement without mucking around with
    catches and throws!

    anyway, thanks for the suggestions ...
     
    valued customer, Apr 3, 2004
    #4
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.