最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - exception handling with generators - Stack Overflow

programmeradmin3浏览0评论

So recently generators kicked in in NodeJS and I'm able to do something like:

Promise.coroutine(function *(query){
    var handle = yield db.connect(Settings.connectionString); //async, returns promise
    var result = yield db.query(query); // async, returns promise
    return result;
});

Now generators are awesome in that they let me do async/await in JS. I really like being able to do that.

However, one issue arises. Generators work with try/catch blocks, so let's say I have code that looks like this:

Promise.coroutine(function *(){
    try{
        var db = yield DBEngine.open("northwind"); // returns promise
        var result = yield db.query("SELECT name FROM users"); // returns promise
        return res;
    } catch (e){
        //code to handle exception in DB query
    }
});

(note,Promise.coroutine is from bluebird)

Notice the bug? There is a reference error, however - the catch will swallow it.

When I put try/catch in 95% of cases what I want to catch is logical errors and I/O errors and not syntax or type errors. I want to be very very aware of those. Callbacks use an err first parameter and in generators I'm not sure of what the substitute is.

How do I deal with exception handling in generator code in JavaScript?

A good solution would allow me to keep stack traces.

So recently generators kicked in in NodeJS and I'm able to do something like:

Promise.coroutine(function *(query){
    var handle = yield db.connect(Settings.connectionString); //async, returns promise
    var result = yield db.query(query); // async, returns promise
    return result;
});

Now generators are awesome in that they let me do async/await in JS. I really like being able to do that.

However, one issue arises. Generators work with try/catch blocks, so let's say I have code that looks like this:

Promise.coroutine(function *(){
    try{
        var db = yield DBEngine.open("northwind"); // returns promise
        var result = yield db.query("SELECT name FROM users"); // returns promise
        return res;
    } catch (e){
        //code to handle exception in DB query
    }
});

(note,Promise.coroutine is from bluebird)

Notice the bug? There is a reference error, however - the catch will swallow it.

When I put try/catch in 95% of cases what I want to catch is logical errors and I/O errors and not syntax or type errors. I want to be very very aware of those. Callbacks use an err first parameter and in generators I'm not sure of what the substitute is.

How do I deal with exception handling in generator code in JavaScript?

A good solution would allow me to keep stack traces.

Share Improve this question edited Dec 22, 2014 at 11:34 Benjamin Gruenbaum asked Nov 8, 2013 at 12:45 Benjamin GruenbaumBenjamin Gruenbaum 276k89 gold badges518 silver badges514 bronze badges 3
  • 3 You already know that you should inspect the error and rethrow it – Esailija Commented Nov 8, 2013 at 12:47
  • can you yield the error itself? – dandavis Commented Nov 14, 2013 at 20:35
  • @dandavis I'm not sure what you mean – Benjamin Gruenbaum Commented Nov 14, 2013 at 22:58
Add a ment  | 

2 Answers 2

Reset to default 10 +50

So basically this is not related to asynchronous system but rather to a particular error handling. Try something like this:

var global_error_check = function(e) {
    if (e && e.name === "ReferenceError") {
        throw e;
    }
    // put other error types here that you don't want to catch
}

try {
    ...
} catch(e) {
    global_error_check(e);
    // handle other errors here
}

According to the most-recent ES6 draft on generators, you can call the generator's "throw" function to resume the generator with a thrown error.

For instance:

function procrastinatingAdd(x, y) {
  var errMsg = "Expected number and got ";
  setTimeout(function() {
    if (isNaN(x)) gen.throw(new TypeError(errMsg + typeof x));
    if (isNaN(y)) gen.throw(new TypeError(errMsg + typeof y));
    gen.next(x + y);
  }, 500);
}

var gen = function* () {
  try {
    var result = yield procrastinatingAdd(1, "foo");
    log(result);
  }
  catch (e) {
    log(e);
  }
};

gen = gen();
gen.next();

Presumably whatever library you were using to manage flow control within your generator (I haven't looked into Promises, but libs like genny and gen-run) should handle this for you such that the libraries you're consuming don't need to be generator-aware.

发布评论

评论列表(0)

  1. 暂无评论