Javascript error stops code execution - javascript

Whenever an error occurs inside an event handler, it stops code execution entirely so the second event callback isn't called.
For example:
$(function() {
window.thisDoesntExist();
}
$(function() {
//Do something unharmful and unrelated to the first event
}
You can easily solve the problem in this (simplified) example by adding try/catch in both anonymous functions, but in reality these functions often add several other event handlers which in turn would require try/catch. I end up with very repetitive code stuffed with try/catch blocks.
My projects has a modular design where each feature is in a different JS (and gets concatenated during a build process). I'm looking for a more generic way to handle errors inside each feature so that the error doesn't stop code execution of the other features.
I already tried following solutions:
- window.onerror (even if you return true in this function, code execution is stopped)
- $(window).error() => deprecated and code execution stops

You could create a helper function to prevent duplication of the same boilerplate code.
function tryFunction(f, onerror) {
try {
if (typeof f == 'function') {
return f();
}
} catch (e) {
return onerror(e);
}
}
$(function() {
var result = tryFunction(window.thisDoesNotExist, function (error) {
alert('Whoops: ' + error);
});
});
I created a little demonstration. It's slightly different but the same idea.

You can simply call if (typeof myFunction == 'function') before calling myFunction()
And optionally wrap it in a generic function like said by Bart to have the choice to log an error in the console if your function does not exists.
If your webapp is huge with many interaction and JS, too many try catch could alter the global performance of your application.

I would try something like this with a wrapper which will handle the try catch for you (see below, or this jsfiddle : http://jsfiddle.net/TVfCj/2/)
From the way I'm (not, and not really) handling the this and the arguments, I guess it's obvious I'm beginning with js. But I hope you get the idea, and it is correct/useful.
var wrapper = {
wrap: function wrap(f) {
return function (args) {
try {
f.apply(null, args);
} catch (ex){
console.log(f.name+" crashed with args "+args);
};
};
}
};
var f1 = function f1Crashes(arg) {
return window.thisDoesntExist();
};
var f2 = function f2Crashes(arg) {
return window.thisDoesntExist();
};
var f3 = function f3MustNotCrash(arg) {
wrapper.wrap(f1)(arg);
wrapper.wrap(f2)(arg);
}
f3('myarg');

The try-catch pattern you mention attempting in your question is the correct way - you want try-catch blocks, not a way to silently truck through module errors (in general always be extremely careful handling exceptions globally and continuing, that way lies data corruption bugs you only find 6 months later).
Your real problem is this:
... in reality these functions often add several other event handlers which in turn would require try/catch. I end up with very repetitive code stuffed with try/catch blocks.
The fix for that is Promise. This is a new structure, native in most browsers but easily shimmed in the slow ones (ahem, IE), that gives you a standard way of managing both the event callback and the exception from the event.
With a Promise your code makes a promise to always do something: either resolve/succeed or reject/fail.
function moduleA() {
return new Promise(function (resolve, reject)
{
try{
var result = window.thisDoesntExist();
resolve(resolve); // Success!
}
catch(err){
reject(err); // Fail!
}
});
}
This is better because rather than nest try-catch blocks in each callback you can instead chain promises:
moduleA().
then(moduleB).
then(moduleC).
catch(errorHandler); // Catch any error from A, B, or C
You can also handle an error and continue:
moduleA().
catch(continuableErrorHandler). // Catch any error from A
then(moduleB).
then(moduleC).
catch(errorHandler); // Catch any error from B or C
You'll still need lots of try-catch blocks in callbacks, but anything that has been wrapped in a Promise can be treated in the same modular way.
Coming next in JS is async and await, but you can use them now with a transpiler. These use promises to make code that is much easier to read, and most importantly (for you) have a single try-catch at the top that gathers exceptions from the entire Promise chain.
This answer is already too long, but I've blogged about that in more detail.
TL;DR: If your problem is "very repetitive [event callback] code stuffed with try/catch blocks" try using Promise instead.

I found a solution. When using setTimeout, the code is executed in a seperate thread, therefor it won't break any other parts of the webpage.
$(function() {
setTimeout(function() {
window.thisDoesntExist();
}, 0);
});
$(function() {
setTimeout(function() {
//Do something unharmful and unrelated to the first event
alert("This passes")
}, 0);
});
In this example, the second function is run, even when the first one throws an error.
Here's a working example: http://jsfiddle.net/mathieumaes/uaEsy/

Related

catching exceptions while waiting for a promise in nodejs

I am writing a library in nodejs, that is wrapping another library. my code is something like this:
function wrapper(functionToWrap) {
return function(param1, param2) {
try {
return functionToWrap(param1, param2);
} catch(err) {
console.log(err);
throw err;
} finally {
finalizeWrapping();
}
}
}
the problem is that my finalizeWrapping function is a function that waits for promises that i collect (by placing some hooks before calling functionToWrap on some of the async apis it uses) to resolve, and only then acts, something like this:
function finalizeWrapping() {
Promise.all(pendingPromises).then(function(values) {
//finalize the wrapping
console.log('all promises fulfilled!');
});
}
the issue is that the error is thrown and node exits (this error should not be handled, since the wrapped function doesn't handle it) before all the promises are resolved and the then block is executed.
my question is: is there anything i can do to work around this, meaning throwing the error to the user appropriately and finish executing the then block, or do i have to change the way i hook the apis to be synchronous and not use a promise?
Thanks in advance to all the helpers :)
EDIT: an attempt to make my question clearer - functionToWrap is not my function, it is a function of a different library (and it can change - meaning i want my code to be able to wrap as many functions as possible). this function is allowed to use async apis (which i may be trying to monkeypatch), and basically it should have as least restrictions as possible - i want the user to be able to write any function and me being able to wrap it.
Not sure if the following can help, you may not have enough reputation to comment although I think you can comment on your own question and it's answers.
const wrapper = functionToWrap =>
function() {
//special type to indicate failed call to functionToWrap
const Fail = function(reason){this.reason=reason;};
//does not matter how many argument. Assuming functionToWrap
// does not rely on "this". If it does then also pass the
// object that functionToWrap is on and replace null with that object
return Promise.resolve(Array.from(arguments))
.then(
//if functionToWrap is on an object pass it to wrapper
// and replace null with that object
args=>functionToWrap.apply(null,args)
)
.catch(
//if functionToWrap throws an error or rejects we will catch it here
// and resolve with a special Fail type value
err=>{
console.log(err);
return new Fail(err)
}
).then(
//since promise cannot fail (its rejection is caught and resolves with Fail)
// this will always be called
//finalize should return Promise.all... and maybe not use a shared
// variable called pendingPromises, global shared mutable variables in async
// functions is asking for trouble
result=>finalizeWrapping().then(
()=>
//if functionToWrap rejected or thew the result will be a Fail type
(result && result.constructor === Fail)
? Promise.reject(result.reason)//reject with the original error
: result//resolve with the functionToWrap result
)
);
}

How to execute code at the very end of a promise chain in q

Let's say you have:
function setTimeoutPromise(ms) {
var defer = Q.defer();
setTimeout(defer.resolve, ms);
return defer.promise;
}
and then you have something like:
function foo(ms) {
return setTimeoutPromise(ms).then(function () {
console.log('foo');
});
}
function afterItAll() {
console.log('after it all');
}
foo(100).then(function () {
console.log('after foo');
}).then(afterItAll);
Is there a way to modify foo so that afterItAll is executed after the after foo block? e.g. something like:
function foo(ms) {
return setTimeoutPromise(ms).then(function () {
console.log('foo');
}).SOMEPROMISECONSTRUCT(function () {
console.log('after it all');
});
}
foo(100).then(function () {
console.log('after foo');
});
The reason I ask is that I am developing an API where the user will make several of these foo calls and it would greatly cut down on the user's code if the after foo code was automatically executed after these API calls. I know I can use a callback to accomplish this, but I'd really like to stick with just using promises.
No, there is none.
Well, let's see what you're asking here:
Is there a way to modify foo so that afterItAll is executed after the after foo block?
This is effectively asking:
Is there any way to know when no more .then handlers will be added to a specific promise?
Which, given an arbitrary function we can decide to add a fooResult.then(function(){}) as the very last thing in the program before we return from it, so it's like asking:
Is there any way to know when/if a function will return?
Which, given a whole program as a function, is like asking:
Is there any way to know if a program will ever halt?
It's not an easy thing to do to say the least. Not only is this feature non existent, it is theoretically impossible.
So how do I deal with it?
Bergi's answer gives you a pretty good idea. The core here, that we fought for in Bluebird is nesting.
Because we want something that's impossible in the general case we have to invert control, like callbacks do:
function transaction(fn){
// Promise.resolve().then( in ES6/Bluebird promises
return Q().then(function(){
return fn()
}).finally(function(){ // same in Bluebird, in ES6 that's `.then(fn, fn)`
console.log("after it all!");
})
}
This would let you do:
transaction(function(){
return setTimeoutPromise().then(more).then(more);
});
Which would run the setTimeoutPromise and then the more and then the other more and will log "after it all" after both are done. This pattern is very useful for DB drivers and resource acquisition.
No, there is no such promise construct. A promise does not - can not - know whether it is the end of a chain, or whether some other code will attach another link to it.
There is however nothing wrong with combining promises and callback code:
function foo(ms, within) {
return setTimeoutPromise(ms).then(function () {
console.log('foo');
})
.then(within)
.then(function afterFooAll() { // possibly use `finally` here?
console.log('cleanup');
});
}
foo(100, function () {
console.log('inside foo');
}) // now returns a promise for cleanup been done
I'm not sure what your actual use case is here, but you also might want to have a look at Bluebird's Promise.using resource management pattern.
OK! I hope my experience helps you.
I had very similar problem.
I wanted mysql connection pool to be released after all sql statement executed,
or failed... like below
getConnection
.then(exeuteSQL('select ...'))
.then(exeuteSQL('select ...'))
.then(null, function(err){ //err handling })
....
.. finally execute pool release
This can be done .done() method like this
getConnection
.then(exeuteSQL('select ...'))
.then(exeuteSQL('select ...'))
.then(null, function(err){ //err handling })
....
.done(function(){
console.log('this line always executed!');
req.conn.release(); // assuming connection attached to request object before
})
PS) My application Environment is node.js and using 'q' promise module

WinJS, return a promise from a function which may or may not be async

I have a situation where my WinJS app wants to call a function which may or may not be async (e.g. in one situation I need to load some data from a file (async) but at other times I can load from a cache syncronously).
Having a look through the docs I though I could wrap the conditional logic in a promise like:
A)
return new WinJS.Promise(function() { // mystuff });
or possibly use 'as' like this:
B)
return WinJS.Promise.as(function() { // mystuff });
The problem is that when I call this function, which I'm doing from the ready() function of my first page like this:
WinJS.UI.Pages.define("/pages/home/home.html", {
ready: function () {
Data.Survey.init().done(function (result) {
// do some stuff with 'result'
});
}
});
When it is written like 'A' it never hits my done() call.
Or if I call it when it's written like 'B', it executes the code inside my done() instantly, before the promise is resolved. It also looks from the value of result, that it has just been set to the content of my init() function, rather than being wrapped up in a promise.
It feels like I'm doing something quite basically wrong here, but I'm unsure where to start looking.
If it's any help, this is a slimmed down version of my init() function:
function init() {
return new WinJS.Promise(function() {
if (app.context.isFirstRun) {
app.surveyController.initialiseSurveysAsync().then(function (result) {
return new WinJS.Binding.List(result.surveys);
});
} else {
var data = app.surveyController.getSurveys();
return new WinJS.Binding.List(data);
}
});
}
Does anyone have any thoughts on this one? I don't believe the 'may or may not be async' is the issue here, I believe the promise setup isn't doing what I'd expect. Can anyone see anything obviously wrong here? Any feedback greatly appreciated.
Generally speaking, if you're doing file I/O in your full init routine, those APIs return promises themselves, in which case you want to return one of those promises or a promise from one of the .then methods.
WinJS.Promise.as, on the other hand, is meant to wrap a value in a promise. But let me explain more fully.
First, read the documentation for the WinJS.Promise constructor carefully. Like many others, you're mistakenly assuming that you just wrap a piece of code in the promise and voila! it is async. This is not the case. The function that you pass to the constructor is an initializer that receives three arguments: a completeDispatcher function, an errorDispatcher function, and a progressDispatcher function, as I like to call them.
For the promise to ever complete with success, complete with an error, or report progress, it is necessary for the rest of the code in the initializer to eventually call one of the dispatchers. These dispatchers, inside the promise, then loop through and call any complete/error/progress methods that have been given to that promise's then or done methods. Therefore, if you don't call a dispatcher at all, there is no completion, and this is exactly the behavior you're seeing.
Using WinJS.Promise.as is similar in that it wraps a value inside a promise. In your case, if you pass a function to WinJS.promise.as, what you'll get is a promise that's fulfilled with that function value as a result. You do not get async execution of the function.
To achieve async behavior you must either use setTimeout/setInterval (or the WinJS scheduler in Windows 8.1) to do async work on the UI thread, or use a web worker for a background thread and tie its completion (via a postMessage) into a promise.
Here's a complete example of creating a promise using the constructor, handling complete, error, and progress cases (as well as cancellation):
function calculateIntegerSum(max, step) {
if (max < 1 || step < 1) {
var err = new WinJS.ErrorFromName("calculateIntegerSum", "max and step must be 1 or greater");
return WinJS.Promise.wrapError(err);
}
var _cancel = false;
//The WinJS.Promise constructor's argument is a function that receives
//dispatchers for completed, error, and progress cases.
return new WinJS.Promise(function (completeDispatch, errorDispatch, progressDispatch) {
var sum = 0;
function iterate(args) {
for (var i = args.start; i < args.end; i++) {
sum += i;
};
//If for some reason there was an error, create the error with WinJS.ErrorFromName
//and pass to errorDispatch
if (false /* replace with any necessary error check -- we don’t have any here */) {
errorDispatch(new WinJS.ErrorFromName("calculateIntegerSum", "error occurred"));
}
if (i >= max) {
//Complete--dispatch results to completed handlers
completeDispatch(sum);
} else {
//Dispatch intermediate results to progress handlers
progressDispatch(sum);
//Interrupt the operation if canceled
if (!_cancel) {
setImmediate(iterate, { start: args.end, end: Math.min(args.end + step, max) });
}
}
}
setImmediate(iterate, { start: 0, end: Math.min(step, max) });
},
//Cancellation function
function () {
_cancel = true;
});
}
This comes from Appendix A ("Demystifying Promises") of my free ebook, Programming Windows Store Apps in HTML, CSS, and JavaScript, Second Edition (in preview), see http://aka.ms/BrockschmidtBook2.
You would, in your case, put your data initialization code in the place of the iterate function, and perhaps call it from within a setImmediate. I encourage you to also look at the WinJS scheduler API that would let you set the priority for the work on the UI thread.
In short, it's essential to understand that new WinJS.Promise and WinJS.Promise.as do not in themselves create async behavior, as promises themselves are just a calling convention around "results to be delivered later" that has nothing inherently to do with async.

Uses of the finally statement

This is a very basic question. In Java I use the finally statement to close resources because "it's a good practice". I've been developing in Javascript and then in Node.js during some years and I've never used the finally statement. I know that in Node.js all of us follow the first parameter error handling pattern. Anyway, the 2 following snippets do the same:
try{
throw 123
}catch (e){
}finally{
console.log(1)
}
.
try{
throw 123
}catch (e){
}
console.log(1)
Both print 1.
Why is finally a keyword if it has no real benefit? The clean up code can be put inside the catch.
finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break.
Just a simple and straightforward example that shows the difference. There is a return that breaks the function completion, but the console.log in finally is called while the last console.log is skipped.
let letsTry = () => {
try {
// there is a SyntaxError
eval('alert("Hello world)');
} catch(error) {
console.error(error);
// break the function completion
return;
} finally {
console.log('finally')
}
// This line will never get executed
console.log('after try catch')
}
letsTry();
But try this:
try {
throw "foo"
} catch (e) {
throw "bar"
} finally {
console.log("baz")
}
console.log("quux")
If a second error is thrown from within the catch block, the code after the try...catch block will not run.
The finally block will always run, even if there is an error in the catch block.
Furthermore, the finally block runs even if a return or break statement stops the code in the try or catch block. return statements in the finally block override return statements in the try or catch block.
function foo() {
try {
return "bar";
} finally {
return "baz";
}
}
foo() // "baz"
oracle docs provide a good answer to this. Bottom line: finally gets called always! Even when you catch only one kind of exception (not the global catch), then finally gets called (after which your application probably breaks if there is no other catch)
the finally block is meant for a special purpose.
finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.
Since it wont effect your business logic,Still it's compiler friendly,In memory aspects.
What if the try-block returns early or throws an exception that you don't handle? You would still want to free the resources you have allocated, right?
EDIT:
The answers to the question seem almost philosphical, there is some 'guessing' and basically 'we believe it should be useful, because it is there, so it should have a use', and 'even Oracle says so'. Or maybe it is there to help the programmer not 'to forget something' or 'accidently exit and not realize it'.
These are almost all valid reasons, but there is also a technical reason.
It helps avoiding code duplication in the cases mentioned, where (a) either the try or one of the catch blocks returns or (b) if within the catch block a second exception is thrown.
In these cases, if some cleanup code or any other code that still needs to be executed after the return and after the second exception, could be placed into the finally block, if it is to be executed both after the try and after the catch block.
You could still do it without the finally block, but the code would have to be duplicated, which the finally block allows you to avoid. This is where you really need it.
So if you are sure you do not miss it as a case of (a) or (b) you could still put the 'finally' code after the try/catch block and omit the finally clause.
But what if the situation changes? When you or another person change the code at some later point it could be forgotten to check if the cleanup code is now skipped in some situation.
So why not always put the cleanup code inside the finally block? And this is what is recommended and what many JavaScript programmers do.
You use it when you want to be sure your code is executed at the end, even if there was an exception during execution :
InputStream is = new FileInputStream("C://test.txt");
try {
//code...
} catch (Exception e) {
//code...
} finally {
is.close();
}
This is a very good question.
There is little to no reason to use finally in javascript, but I can imagine situations where it could be of practical use.
Suppose you have a webpage where you show a certain div after some user action, e.g. button clicked.
The div shows some logging for instance for the action the user requested.
After the action is complete (error or no error), you want to be sure to hide the div again. For that you can use the finally clause.
function doSomething() {
var d = document.getElementById("log");
show(d);
try {
... execute action ...
} catch(e) {
log(e);
} finally {
hide(d);
}
}
In general, as you mentioned, exceptions are less and less used in JavaScript in favor of error callbacks.
So, one could as well ask, what good uses are for exceptions in JavaScript in general.
The problem is with your example. There are cases when you don't want to catch the exception.
try {
if (Math.random() > 0.5) throw 123
}
finally {
console.log(1)
}
In these cases all you could do is rethrowing the exception if you don't want to use finally.
try {
if (Math.random() > 0.5) throw 123
}
catch (e) {
console.log(1)
throw e
}
console.log(1)
or maybe
try {
if (Math.random() > 0.5) throw 123
console.log(1)
}
catch (e) {
console.log(1)
throw e
}
Both alternative solutions lead to code duplication, that's why you need the finally keyword. It is used most of the time to free up unused resources. Forgetting about it may lead to unwanted locks or connections or memory leaks. I guess in some cases even a smart GC cannot prevent it.
In Java, if there's an Exception thrown that is not matched by any of the catch-blocks execution will break and any open resources will be left open.
The finally block will always be executed, even if an uncaught exception occurs.

Using Node.js, is there some semantic to tell me when code is going to leave the current stack?

Right now, it's a mystery to me if my try/catch blocks are going to work at all. I set them around code, and then, because something in the code was "asynchronous", which appears to be a fancy way of saying forked to another thread/process at the OS level, the try/catch is ignored if it happens in that code.
I'm fine with that, I just want to know if there's some indication of this? By convention, I'm given to understand, if a call asks for a callback, it's asych, otherwise it's not. I get why a callback means asych, but I'm afraid that the reverse isn't always true: THere's nothing stopping me from surrounding a call with a try/catch that gets loaded into a new call stack and also doens't ask for a callback. This seems really messy to me, and I'd like a little more control over my try/catches than using the default callback that all uncaught exceptions are handled by, if possible.
Is there a semantic to tell me when code is going to leave the
current stack?
UPDATE: here is an example:
var UserSchema = new mongoose.Schema({
email: {type: String, unique: true},
password: String,
firstName: String,
lastName: String,
created_at: {type: Date, default: Date.now},
updated_at: Date
});
var User = mongoose.model('User', UserSchema);
var users = [
{email: 'foo#bar.com', firstName: 'Justin', lastName: 'Jones'},
{email: 'foo#bar.com', firstName: 'Justin', lastName: 'Jones'}
];
users.forEach(function(user) {
var newUser = new User(user);
newUser.save(function(err, obj) {
if (!err) console.log("Saved: ", obj.email);
});
});
Given the code above, there's no way to catch an exception inside of save(), as it happens in another call stack. Is there any way for me to externally know that's what's about to happen when I call save()?
UPDATE: Everyone telling me to use handlers for this should maybe read this? It's clearly suggesting not to deal with exceptions that aren't caught in their "thread execution", quotes since it only acts like a thread.
"Asynchronous" is not "a fancy way of saying forked to another thread/process".
JavaScript is single-threaded. End of story. There is no forking at the language level.
"Asynchronous" means just what it says: The order of execution is not the order of the code. Some bits of the code - callback functions - will execute at some point in time, when a certain event occurs. It is an event-based programming model.
Consider this simple example:
function hello () { alert("Hello!"); }
setTimeout(hello, 2000);
This is an asynchronous callback in its most basic form. You have a callback handler - the function hello - and an event generator, in this instance a time-based one.
Once the event occurs (2s have have passed), the callback handler is called.
Now for a modification:
function hello() { alert(foo.bar); }
try {
setTimeout(hello, 2000);
} catch (ex) {
alert(ex.message);
}
We introduce a try-catch block around setTimeout. It guards the registration of a callback, nothing more. Most likely this step will succeed, hence the try-catch block will never do anything. The fact that the callback itself will fail in 2 seconds from now does not affect the try-catch block, naturally. This is the behavior you find confusing.
Now for another modification:
function hello() {
try {
alert(foo.bar);
} catch (ex) {
alert("foo.bar is not defined");
}
}
setTimeout(hello, 2000);
Now the try-catch block guards the step that can actually fail. This implies that you must use try-catch blocks where the errors can occur, not generally wrap them around large sections of your program (which is what you seem to do).
But how to get the exception to do do something useful and configuable? By introducing more callbacks, naturally.
function hello(onError) {
try {
alert(foo.bar);
} catch (ex) {
onError("foo.bar is not defined", ex);
}
}
function errorHandler(customMessage, exception) {
alert(customMessage);
// or do something with exception
}
setTimeout(function () {
hello(errorHandler)
}, 2000);
As per your added example:
var saveUsers = function(users, onSuccess, onError) {
users.forEach(function(user) {
var newUser = new User(user);
newUser.save(function(err, obj) {
if (err) {
onError(err, obj);
return false;
} else {
onSuccess(obj);
}
});
});
}
var users = [
{email: 'foo#bar.com', firstName: 'Justin', lastName: 'J'},
{email: 'foo#bar.com', firstName: 'Justin', lastName: 'J'}
];
saveUsers(
users,
function (user) { console.log("Saved: ", user.email); },
function (err, user) { console.log("Could not save: ", user.email); }
});
The semantic is literally just when the function you called has finished executing. If it spawns an I/O process and registers an event, your try-catch block won't surround that because it's executed on another loop through the implicit Javascript event loop.
The presence or nonexistence of a callback parameter in the function you're executing has no bearing whatsoever on whether or not work started by the function will cause an event to fire off somewhere else. An EventEmitter-based object registers handlers with the .on('eventName', functionName) mechanism, so multiple events and multiple handlers can be accessing the same "work" but that is all kicked off by a function that takes no callbacks. While the Array object's forEach method takes a callback and is synchronous.
Simply put, nothing beyond the event loop barrier should cause a Javascript exception to be thrown. Only the code on the Javascript side of things can. So you put your try-catch blocks, if needed, on that side: In your function that calls the possibly async code if that function will possibly throw an error, and in your callback function itself if it calls something that could possibly throw an error. If it's async, they are two separate call stacks from Javascript's perspective, so they have different try-catch scopes; if it's sync, you'll just have one extra set of try-catch checks, and at least you'll have a better idea of what could have thrown the error.
Personally, I think try-catch just doesn't work in a language like Javascript, and was added to make it more Java-like, so I try to avoid code that uses throw for Node.js stuff. (Exceptions are if it's using them only for initial configuration of the library/object that can't work or if it's using it [poorly, in my opinion, because of the execution overhead] as an internal way to break out of deep synchronous code and doesn't expose it to me.)
EDIT: To better explain the callstack in Javascript, here's a simple ASCII diagram showing each level of the stack versus time:
== Javascript Event Loop =========================================================
== My Awesome Function ====================================== == My callback ==
== Call to an async library ====================
== I/O request and callback registration ===
Anything that is thrown by My callback will be sent straight back to the Javascript Event Loop and can only be caught by registering a process.on('uncaughtException', myFunc) handler to take care of it at that point. Basically, any code of your own can certainly use try-catch, but it should never throw if it'll be called directly as an event handler.
As for your recent edit to your question async.forEach will solve your issue. You pass it the array to iterate over, then the function to execute on each item in the array, and then a "finally"-style function to either handle an error or continue your code from there.
Nathan: I'm not going to go into the bigger question of finding out "when code is going to leave the current stack". I can help you with saving your users though. I recommend the great async library:
function saveUser(user, callback) {
new User(user).save(callback);
}
async.forEach(users, saveUser, function(err, results) {
// Respond
});
If you're simply using callback functions, then it doesn't matter. NodeJS is single-threaded, thus everything is on the same call stack.
BUT! You're right about NodeJS may sometimes "leave" the current call stack. The leave is in quote because it's not really leaving the current call stack but simply returning to the root call (process.nextTick()). Then on the next tick, it's spawn a "new" call stack.
If you want a semantic, I guess you can say that anywhere that you're using EventEmitter, you're passing that callback function to the next tick and therefore "moving" it to another call stack. (But even so, it's not entirely true, because EventEmitter actually dispatches event on the current tick).

Categories

Resources