Is "ECONNREFUSED, Connection refused" uncatchable?

3,293 views
Skip to first unread message

foulmawcur

unread,
Sep 21, 2010, 3:45:59 PM9/21/10
to nodejs
I'm new and experimenting with nodejs / couchdb.

I wrote a script that is supposed to hit my CouchDB instance:

// code: --------------

try {
var couchdb = http.createClient(5984, '127.0.0.1');
var request = couchdb.request('GET', '/', {'host': '127.0.0.1'});
request.end();
request.on('response', function (response) {
console.log('STATUS: ' + response.statusCode);
console.log('HEADERS: ' + JSON.stringify(response.headers));
response.setEncoding('utf8');
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
}
catch (err) {
console.log('Hey! I caught an error: ' + err);
}
console.log('Does this work?');

// end code:--------------

If I forget to start my couchdb instance (i.e. the http server is not
running), I had hoped that my code would recover, but it doesn't seem
that I'm able to catch the error:

// result:-----------------
Does this work?

node.js:63
throw e;
^
Error: ECONNREFUSED, Connection refused
at IOWatcher.callback (net:854:22)
at node.js:757:9

// end result:-----------------

Are these types of errors uncatchable, or am I totally missing
something?

thanks in advance,
a future evangelist

Timothy Caswell

unread,
Sep 21, 2010, 4:13:30 PM9/21/10
to nod...@googlegroups.com
try..catch can only catch exceptions thrown in the same stack it was defined in. All callbacks that get called by the event loop start on a fresh stack. This includes network events, filesystem events, timeout or interval events, even nextTick events.

The practical problem is that you have to try..catch every level of callback if it's a handler to some event.

Node alto provides a global event on the process global called "uncaughtException" This will attempt to be a catchall for uncaught exceptions.

> --
> 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.
>

Александр Лозовюк

unread,
Sep 21, 2010, 4:13:41 PM9/21/10
to nod...@googlegroups.com
Try to add listener at 'error' event...

2010/9/21 foulmawcur <alan....@gmail.com>:

> --
> 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.
>
>

--
C уважением, Александр Лозовюк
Alpha-Beta-Release Blog
http://abrdev.com

Mihai Călin Bazon

unread,
Sep 21, 2010, 4:14:14 PM9/21/10
to nod...@googlegroups.com
Not familiar with CouchDB, but the problem is probably more general:
by the time the exception is thrown, the try/catch block will have
already been exited. Recovering from such errors is one of trickiest
things to do in an asynchronous style (I'm sure there are solutions,
I'm sure they are not nice, and I'll be watching this thread).

To exemplify your problem outside the CouchDB context, here's a sample:

try {
setTimeout(function() {
throw "ERROR";
}, 0);
catch(ex) {
print("I got it!");
}

You won't ever see "I got it!", because the try/catch block exits
before the inner function runs.

Cheers,
-Mihai

> --
> 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.
>
>

--
Mihai Bazon,
http://mihai.bazon.net/blog

Robert Newson

unread,
Sep 21, 2010, 4:23:45 PM9/21/10
to nod...@googlegroups.com
You might have more success with client.on('error', function (err) {
/* handle */ });

2010/9/21 Mihai Călin Bazon <mihai...@gmail.com>:

Tim Caswell

unread,
Sep 21, 2010, 4:42:26 PM9/21/10
to nodejs
Yes, there is also a special nodism where if an "error" event is
emitted, but not listened to, node will throw it as an exception. If
your exception is being caused by an error event, then adding a
listener for the "error" event will catch the error.


On Sep 21, 1:13 pm, Александр Лозовюк <aleks.rai...@gmail.com> wrote:
> Try to add listener at 'error' event...
>
> 2010/9/21 foulmawcur <alan.he...@gmail.com>:
> > For more options, visit this group athttp://groups.google.com/group/nodejs?hl=en.

Tim Caswell

unread,
Sep 21, 2010, 4:51:21 PM9/21/10
to nodejs
On Sep 21, 1:14 pm, Mihai Călin Bazon <mihai.ba...@gmail.com> wrote:
> I'm sure there are solutions,
> I'm sure they are not nice, and I'll be watching this thread.
>

<http://github.com/creationix/step> wraps all function callbacks in
automatic try..catch blocks and helps some with this. Also there is
this experiment I'm started today that will be part of my jsconf talk
on Saturday. <https://gist.github.com/358482dffb84ecf1a0c3> I like
the wrap() utility because as long as you wrap all event handlers,
then their exceptions will be routed to the callback. wrap will be
the first thing in the stack trace after node's internal event
dispatcher.

If you don't want to use a utility that wraps try..catch for you, then
you have to be careful to not throw exceptions when you're not ready
to catch them in that same stack. A simple inline try..catch around
something dangerous like JSON.parse that forwards the error to a
callback can go a long ways to making a server more reliable.

The most important thing is to have a sound understand of what creates
a new stack and what doesn't. If you don't know where you code gets
called from it's hard to predict it's behavior.

Mikeal Rogers

unread,
Sep 22, 2010, 7:14:37 AM9/22/10
to nod...@googlegroups.com
This is a constant point of confusion for people

First, if you don't handle error events they throw.

Second, http requests basically never emit error events only client emits errors because it's responsible for all the socket activity.

var client = http.createClient(host, port)
client.addListener('error', function .........

Of course it ends up becoming a mess to try and scope your error handling to be aware of the current request it was doing when the error occured. This is why my request library does that for you and gives you a single callback that gets any errors on the client during that request and the response object + buffered body.


-Mikeal


--

foulmawcur

unread,
Sep 22, 2010, 10:06:58 AM9/22/10
to nodejs
Thanks for the responses! But, of course! The try... catch section of
code is passed by the time the error is thrown! I even proved that in
my example and output. I guess that is how ingrained non-asynchronous
language practices can be.

After reading a few responses above, I was also trying to determine
how I would know that http.ClientRequest would emit an 'error' event.
Well... http.ClientRequest extends EventEmitter... and there you go.

Mikeal, I came across your request library (and blog entry) yesterday
independently. Thanks for the link though. I'll try to get an
understanding of what you did here.
> > nodejs+un...@googlegroups.com<nodejs%2Bunsu...@googlegroups.com>
> > .

Mikeal Rogers

unread,
Sep 22, 2010, 11:04:12 AM9/22/10
to nod...@googlegroups.com
The thing about event emitters is that they can emit any event at any time so just looking at the implementation of the object doesn't show you everything, you also need to look at where it's passed around because any one at any time could emit a random event on it.

Is there some place in the docs that we can call out the fact that unhandled error events will throw and there isn't really any way to use try/catch, you're gonna need to add a handler for error events?

-Mikeal

To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages