koajs / discussions

KoaJS Discussions
2 stars 2 forks source link

How can I catch EADDRINUSE? #6

Open christianbundy opened 4 years ago

christianbundy commented 4 years ago

I've tried to wrap listen() in a try...catch but it doesn't actually catch the error. I don't want to print a stack-trace, I want to print a helpful error message. How can I catch this error? I've searched but can't find any other discussions about this problem.

Thanks a bunch for this project!

Backlink: https://github.com/fraction/oasis/issues/129

ralyodio commented 4 years ago
process.on('uncaughtException', function(err) {
    if(err.errno === 'EADDRINUSE')
         console.log(...);
    else
         console.log(err);
    process.exit(1);
});  
christianbundy commented 4 years ago

Thanks, I hadn't considered that! :man_facepalming: Is this something that you think Koa should be throwing or is uncaughtException the expected error behavior?

adjenks commented 4 years ago

When you call listen() Koa creates a server on the fly using the http module, seen here: https://github.com/koajs/koa/blob/422e539e8989e65ba43ecc39ddbaa3c4f755d465/lib/application.js#L77-L81 According to the node documentation, you can handle that error like this:

server.on('error', (e) => {
  if (e.code === 'EADDRINUSE') {
    console.log('Address in use, retrying...');
    setTimeout(() => {
      server.close();
      server.listen(PORT, HOST);
    }, 1000);
  }
});

But since Koa calls listen before you can touch the server object, you can't. You'll have to make the server yourself like so:

const server = http.createServer(yourKoaApp.callback())
/* -- insert error handling code from above -- */
server.listen(portNumberOrWhatever)

I think if this were to be fixed in Koa, it could be done a variety of ways, but the most sensible to me would be to just depreciate the listen function because it doesn't really do much except save a line of code and obscure this error in the process.

As per the docs it's sugar: https://github.com/koajs/koa/blob/master/docs/api/index.md#applisten

jdmarshall commented 4 years ago

Express has essentially the same bootstrap code, and has the same problem.

Port in use triggers an uncaught error instead of throwing from listen(), which means the 'problem' is in http.

kyr0 commented 2 years ago

Yeah, bad API design :/