Javascript try...catch...else...finally like Python, Java, Ruby, etc - Stack Overflow

How can Javascript duplicate the four-part try-catch-else-finally execution model that other languages

How can Javascript duplicate the four-part try-catch-else-finally execution model that other languages support?

A clear, brief summary is from the Python 2.5 what's new. In Javascript terms:

// XXX THIS EXAMPLE IS A SYNTAX ERROR
try {
  // Protected-block
} catch(e) {
  // Handler-block
} else {
  // Else-block
} finally {
  // Final-block
}

The code in Protected-block is executed. If the code throws an exception, Handler-block is executed; If no exception is thrown, Else-block is executed.

No matter what happened previously, Final-block is executed once the code block is complete and any thrown exceptions handled. Even if there’s an error in Handler-block or Else-block and a new exception is raised, the code in Final-block is still run.

Note that cutting Else-block and pasting at the end of Protected-block is wrong. If an error happens in Else-block, it must not be handled by Handler-block.

How can Javascript duplicate the four-part try-catch-else-finally execution model that other languages support?

A clear, brief summary is from the Python 2.5 what's new. In Javascript terms:

// XXX THIS EXAMPLE IS A SYNTAX ERROR
try {
  // Protected-block
} catch(e) {
  // Handler-block
} else {
  // Else-block
} finally {
  // Final-block
}

The code in Protected-block is executed. If the code throws an exception, Handler-block is executed; If no exception is thrown, Else-block is executed.

No matter what happened previously, Final-block is executed once the code block is complete and any thrown exceptions handled. Even if there’s an error in Handler-block or Else-block and a new exception is raised, the code in Final-block is still run.

Note that cutting Else-block and pasting at the end of Protected-block is wrong. If an error happens in Else-block, it must not be handled by Handler-block.

Share Improve this question asked Feb 2, 2011 at 8:23 JasonSmithJasonSmith 73.7k23 gold badges126 silver badges149 bronze badges 0
Add a comment  | 

5 Answers 5

Reset to default 49

I know this is old, but here is a pure syntax solution, which I think is the proper way to go:

try {
    // Protected-block
    try {
        // Else-block
    } catch (e) {
        // Else-handler-block
    }
} catch(e) {
    // Handler-block
} finally {
    // Final-block
}

The code in Protected-block is executed. If the code throws an error, Handler-block is executed; If no error is thrown, Else-block is executed.

No matter what happened previously, Final-block is executed once the code block is complete and any thrown errors handled. Even if there’s an error in Handler-block or Else-block, the code in Final-block is still run.

If an error is thrown in the Else-block it is not handled by the Handler-block but instead by the Else-handler-block

And if you know that the Else-block will not throw:

try {
    // Protected-block
    // Else-block
} catch(e) {
    // Handler-block
} finally {
    // Final-block
}

Moral of the story, don't be afraid to indent ;)

Note: this works only if the Else-handler-block never throws.

Extending the idea of jhs a little, the whole concept could be put inside a function, to provide even more readability:

var try_catch_else_finally = function(protected_code, handler_code, else_code, finally_code) {
  try {
    var success = true;
    try {
      protected_code();
    } catch(e) {
      success = false;
      handler_code({"exception_was": e});
    }
    if(success) {
      else_code();
    }
  } finally {
    finally_code();
  }
};

Then we can use it like this (very similar to the python way):

try_catch_else_finally(function() {
  // protected block
}, function() {
  // handler block
}, function() {
  // else block
}, function() {
  // final-block
});

I know the question is old and answers has already given but I think that my answer is the simplest to get an "else" in javascripts try-catch-block.

var error = null;
try {
    /*Protected-block*/
} catch ( caughtError ) {
    error = caughtError; //necessary to make it available in finally-block
} finally {
    if ( error ) {
        /*Handler-block*/
        /*e.g. console.log( 'error: ' + error.message );*/
    } else {
        /*Else-block*/
    }
    /*Final-block*/
}

Javascript does not have the syntax to support the no-exception scenario. The best workaround is nested try statements, similar to the "legacy" technique from PEP 341

// A pretty-good try/catch/else/finally implementation.
try {
  var success = true;
  try {
    protected_code();
  } catch(e) {
    success = false;
    handler_code({"exception_was": e});
  }
  if(success) {
    else_code();
  }
} finally {
  this_always_runs();
}

Besides readability, the only problem is the success variable. If protected_code sets window.success = false, this will not work. A less readable but safer way uses a function namespace:

// A try/catch/else/finally implementation without changing variable bindings.
try {
  (function() {
    var success = true;
    try {
      protected_code();
    } catch(e) {
      success = false;
      handler_code({"exception_was": e});
    }
    if(success) {
      else_code();
    }
  })();
} finally {
  this_always_runs();
}

Here's another solution if the problem is the common one of not wanting the error callback to be called if there is an uncaught error thrown by the first callback. ... i.e. conceptually you want ...

try { 
    //do block 
    cb(null, result);
} catch(err) {
    // err report
    cb(err)
}

But an error in the success cb causes the problem of cb getting called a second time. So instead I've started using

try { 
    //do block 
    try { 
        cb(null, result); 
    } catch(err) { 
        // report uncaught error 
    }
} catch(err) {
    // err report
    cb(err)
}

which is a variant on @cbarrick's solution.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1737072358a3920615.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信