I've been researching the proper way to handle errors in Node and have found some good answers here on StackOverflow and on NodeJS' site, such as How do I prevent node.js from crashing? try-catch doesn't work and the NodeJS docs themselves: http://nodejs.org/api/domain.html.
However, I'm left with a couple questions regarding when and where to use try/catch and/or domains. I realize this has to do with asynchronous vs synchronous code, but even inside the sample code provided on NodeJS' site regarding domains, they use a try/catch inside the domain's error handler. Could someone explain this in some detail, wouldn't the try/catch fail to catch asynchronous errors inside the error handler?
Beyond that, NodeJS' docs suggest that you should still end the process on an exception, and that's why the code from the Domain docs suggest using a cluster to fork a new child process/worker when the exception is caught. The main reason given is:
By the very nature of how throw works in JavaScript, there is almost never any way to safely "pick up where you left off", without leaking references, or creating some other sort of undefined brittle state.
Can someone explain this? What is the nature of how throw works in Javascript? Why would resources be leaking like crazy? And is it always really necessary to restart the process or kill/start a worker?
For example, I was implementing the JugglingDB ORM and at one point forgot to launch my local mysql server. I encountered an ECONNREFUSED
error which crashed the process. Realizing this could happen in a production environment (DB crashes or is temporarily unavailable), I wanted to catch this error and handle it gracefully; retry the connection, maintain a state variable about the DB, and possibly handle requests by responding with a temporarily unavailable message. Try/Catch simply didn't catch the error and although I see I could use a domain, using the recommended strategy, I would be in an endless loop of killing and starting workers until the DB was back online.
JugglingDB, for whatever reason, only has a "connected" event, but doesn't have any kind of callback function which passes an error object; it tries to connect the moment you instantiate the class and it throws errors which are not caught and emitted in graceful way. This has made me want to look at other ORMs, but that still doesn't answer my questions regarding how to handle such a situation. Would it be wrong to use a domain to catch potential connection errors and handle it gracefully without starting a new process?
Here is the question/issue I posted to the JugglingDB github: https://github.com/1602/jugglingdb/issues/405, and here is the stack trace from the error produced by JugglingDB when a server doesn't exist (only occurs when the pooling option is enabled):
Error: connect ECONNREFUSED
at errnoException (net.js:901:11)
at Object.afterConnect [as oncomplete] (net.js:892:19)
--------------------
at Protocol._enqueue (/Users/aaronstorck/Sites/site/node_modules/jugglingdb-mysql/node_modules/mysql/lib/protocol/Protocol.js:110:48)
at Protocol.handshake (/Users/aaronstorck/Sites/site/node_modules/jugglingdb-mysql/node_modules/mysql/lib/protocol/Protocol.js:42:41)
at PoolConnection.Connection.connect (/Users/aaronstorck/Sites/site/node_modules/jugglingdb-mysql/node_modules/mysql/lib/Connection.js:101:18)
at Pool.getConnection (/Users/aaronstorck/Sites/site/node_modules/jugglingdb-mysql/node_modules/mysql/lib/Pool.js:42:23)
at Pool.query (/Users/aaronstorck/Sites/site/node_modules/jugglingdb-mysql/node_modules/mysql/lib/Pool.js:185:8)
at initDatabase (/Users/aaronstorck/Sites/site/node_modules/jugglingdb-mysql/lib/mysql.js:62:20)
at initializeConnection (/Users/aaronstorck/Sites/site/node_modules/jugglingdb-mysql/lib/mysql.js:49:9)
at Object.initializeSchema [as initialize] (/Users/aaronstorck/Sites/site/node_modules/jugglingdb-mysql/lib/mysql.js:33:5)
at new Schema (/Users/aaronstorck/Sites/site/node_modules/jugglingdb/lib/schema.js:105:13)
at Application.loadConnections (/Users/aaronstorck/Sites/site/core/application.js:95:40)
Process finished with exit code 8
Thank you in advance for any part of this you can help me understand! :)