async try/catch replacement

137 views
Skip to first unread message

Liam

unread,
Nov 12, 2011, 1:22:30 PM11/12/11
to nodejs
This gem by Mikeal about an async-compatible alternative to try/catch
was buried in another fierce debate on async code style.

I'd like to suggest that the API use a term like "tryCatch" instead of
"createDomain"

On Nov 10, 8:42 pm, Mikeal Rogers <mikeal.rog...@gmail.com> wrote:
> The basic idea is this (although this is *not* the exact API):
>
> var d = process.createDomain()
> // arbitrary code
> d.stop()
> d.on('error', function (err) { })
> d.on('end', function () {})
>
> Any code that runs between creation and the stop call will be in the domain. Any callbacks added to the event system will also be in the domain. So if:
>
> function a (cb) {
> setTimeout(cb, 100)
> }
>
> function b (cb) {
> setTimeout(function () {
> throw new Error('asdf')
> }, 100)
> }
>
> var d = process.createDomain()
> a(function () {
> setTimeout(function () {
> b(function () {})
> }, 100)
> })
> d.stop()
>
> So In this code, event tho all these functions are being called in the future the event loop they are all attached to this domain and the throw in b will still be trapped by the domain. Once there is nothing left in the event system attached to the domain it fires the end event.
>
> Hope that explains it. There is still some talk about parent/child relationships of domains but that isn't ironed out yet.
>
> -Mikeal

Marco Rogers

unread,
Nov 12, 2011, 2:10:05 PM11/12/11
to nod...@googlegroups.com
Ah, that's a very nice connection. The domains proposal does have elements that relate to sync try/catch. I like that characterization too. But I'm not sure we should call it tryCatch because domains can also be used in other ways. People will use it to manage arbitrary "domains" of state. Most commonly this will be a domain for request.  This will allow, say express, to manage state for a single request and always be able to associate any execution state with the current request. But this isn't the same as localized execution where you want to try/catch.

I guess maybe that's why people are also concerned about whether domains will nest in a parent child fashion. You'd have a request level domain, some domains internal to that for some complex try/catch behavior. Maybe some invisible domains below that, used by a data access layer. The more I think about it, the more confused I get when considering complex use cases. I hope it's ready for some practical testing soon.

I may have botched many of the ideas behind this thing. Feel free to correct any of my misunderstandings.

:Marco

Floby

unread,
Nov 13, 2011, 1:39:36 PM11/13/11
to nodejs
Is that the one that hooks into the functions that register callbacks
in the event loop?
I saw this go by and thought it was interesting but the debate ended
up on streamline, fibers and the usual stuff.

Marak Squires

unread,
Nov 13, 2011, 4:46:21 PM11/13/11
to nod...@googlegroups.com
Check out https://github.com/indutny/deadbolt


--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en



--
-- 
Marak Squires
Co-founder and Chief Evangelist
Nodejitsu, Inc.

Adam Crabtree

unread,
Nov 13, 2011, 5:31:33 PM11/13/11
to nod...@googlegroups.com
I released an async try/catch with long stack traces a while back, called not unexpectedly "trycatch", http://github.com/crabdude/trycatch:

trycatch(function try() {
  process.nextTick(function(){throw new Error('caught');});
}, function catch(e) {
  console.log(e.stack);
});

I also went into the details a little bit more here on the current "[nodejs] try/catch/throw (was: My Humble Co-routine Proposal)" thread, https://groups.google.com/group/nodejs/browse_thread/thread/d444acb2c231ad45#msg_2acd175ed211b4c4.

I also rolled it into step and added error-coalescing and called it stepup, http://github.com/crabdude/stepup, if anyone's interested.

@Marak

That's pretty sweet. I'll have to check that out and maybe fold it into stepup. =)

--
Better a little with righteousness
       than much gain with injustice.
Proverbs 16:8

Floby

unread,
Nov 14, 2011, 5:27:06 AM11/14/11
to nodejs
Thanks Adam, that was the one I was thinking about.

On Nov 13, 11:31 pm, Adam Crabtree <atcrabt...@gmail.com> wrote:
> I released an async try/catch with long stack traces a while back, called
> not unexpectedly "trycatch",http://github.com/crabdude/trycatch:
>
> trycatch(function try() {
>   process.nextTick(function(){throw new Error('caught');});}, function catch(e) {
>
>   console.log(e.stack);
>
> });
>
> I also went into the details a little bit more here on the current
> "[nodejs] try/catch/throw (was: My Humble Co-routine Proposal)" thread,https://groups.google.com/group/nodejs/browse_thread/thread/d444acb2c...
> .
>
> I also rolled it into step and added error-coalescing and called it stepup,http://github.com/crabdude/stepup, if anyone's interested.

Liam

unread,
Nov 14, 2011, 2:18:59 PM11/14/11
to nodejs
On Nov 12, 11:10 am, Marco Rogers <marco.rog...@gmail.com> wrote:
> Ah, that's a very nice connection. The domains proposal does have elements
> that relate to sync try/catch. I like that characterization too. But I'm
> not sure we should call it tryCatch because domains can also be used in
> other ways. People will use it to manage arbitrary "domains" of state. Most
> commonly this will be a domain for request.  This will allow, say express,
> to manage state for a single request and always be able to associate any
> execution state with the current request. But this isn't the same as
> localized execution where you want to try/catch.
>
> I guess maybe that's why people are also concerned about whether domains
> will nest in a parent child fashion. You'd have a request level domain,
> some domains internal to that for some complex try/catch behavior. Maybe
> some invisible domains below that, used by a data access layer. The more I
> think about it, the more confused I get when considering complex use cases.
> I hope it's ready for some practical testing soon.

Back on the "domains" proposal/solution...

I'd really like to see this be easy for local try/catch, as well as
whole-request:

function stuff() {
var tc = process.tryCatch(function(err) { // takes the error handler
finish(); // won't throw
})
io.async(..., function(err, result) {
if (err) throw err;
io.asinc(..., function(err, data) {
if (err) throw err;
finish(result, data); // may throw
tc.end(); // "end()" fires the end event
})
})
}

Also, will this work with non-core async libraries?

Marco Rogers

unread,
Nov 14, 2011, 3:17:15 PM11/14/11
to nod...@googlegroups.com

Also, will this work with non-core async libraries?

Yes, domains is meant to be a generally usable new paradigm for both core and userland. And the nice thing is, if you start a domain in your code and then use a third-party module that doesn't care about them, your domain will catch all errors from that module anyway. It's meant to be interoperable but viral.

:Marco 

Adam Crabtree

unread,
Nov 14, 2011, 3:35:04 PM11/14/11
to nod...@googlegroups.com
This looks nearly identical to what trycatch already does, except it's utilizing an EventEmitter pattern. The only discernible difference to me apart from the fact that trycatch wraps your code in a new closure, which may or may not be desirable, is that of the "end" event which is equivalent to a "finally." Perhaps I'll add that later this week. I prefer mine as it's familiar (try/catch/finally), but no particular reason why one has to win vs the other I suppose. =)

Someone please correct me if I'm wrong.

Thanks,
Adam Crabtree

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Liam

unread,
Nov 14, 2011, 3:50:18 PM11/14/11
to nodejs
On Nov 14, 12:35 pm, Adam Crabtree <atcrabt...@gmail.com> wrote:
> This looks nearly identical to what trycatch already does, except it's
> utilizing an EventEmitter pattern. The only discernible difference to me
> apart from the fact that trycatch wraps your code in a new closure, which
> may or may not be desirable, is that of the "end" event which is equivalent
> to a "finally." Perhaps I'll add that later this week. I prefer mine as
> it's familiar (try/catch/finally), but no particular reason why one has to
> win vs the other I suppose. =)

I'd sure prefer the core solution use the established terminology:

var tc = process.tryCatch() // or tryAsync, try_a, ...
tc.on('catch', function(err) {})
tc.on('finally', function() {})
throw new Exception('catch me');
tc.finally();
Reply all
Reply to author
Forward
0 new messages