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.
A good solution would allow me to keep stack traces.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With