Handling Uncaught Exceptions in Node.js is not very easy
Problems caused by uncaught exceptions
How to deal with uncaught exceptions
An application without uncaught exceptions
Crash your application
Pretend you don’t see the error?
The application crashes, prints the log, and then restarts
Use the Domains module [Translator's Note: Now obsolete]
Conclusion
Due to the single-threaded nature of Node.js, uncaught exceptions are a problem for application development Issues worth noting during the process. Node.js follows a callback pattern of errors first, data second. We often see this example: when the callback function returns an error object, the error is thrown immediately.
var fs = require('fs'); fs.readFile('somefile.txt', function (err, data) { if (err) throw err; console.log(data); });
If you run this program, and assuming you don't have the file somefile.txt
, an error will be thrown.
Error: ENOENT, open 'somefile.txt'
This will cause the process to crash and affect the entire APP.
This is intentional, Node.js does not intend to separate your application and service.
What is the best way to handle uncaught exceptions? There are so many ways:
Your application should not have uncaught errors, it's crazy.
It's also crazy that you should let your app find uncaught exceptions after a crash and then fix them.
Turning a blind eye to a mistake and not dealing with it—that’s what most people do, and it sucks.
You should let your application print out the error log after a crash, and then use upstart
, forever
, monit
Something like this restarts the process. This method is very practical.
[Translator's Note: Now obsolete] You should start using the Domains module to handle errors. This is the only way to go, although this is still an experimental feature of Node.js.
Now let’s expand these methods in detail.
The concept of "an application without uncaught exceptions" is weird to me, any application will have exceptions at some point and it may be Uncaught exception. If you insist on this point and throw errors to users, then I think you should be prepared to get a phone call in the middle of the night and be told that the service has crashed.
The only defence I can find in this opinion is the fail fast argument. You are going to fix your application quickly if it unavailable. If an application without uncaught exceptions is letting denial your application crash is acceptance. But you are still pushing exception handling onto your users. (Forgive me for not being able to figure out how to translate this paragraph. If you have good ideas, please contact me as soon as possible!)
Many people do this:
<p style="margin-bottom: 7px;">process.on('uncaughtException', function (err) {<br/> console.log(err);<br/>})<br/></p>
This is bad. When an uncaught exception is thrown, you should realize that your application is in an abnormal state. In this case You can't run your program reliably.
Felix Geisendörfer
who originally proposed the process.on event now advocates its removal.
With this method you can make your application crash immediately when an uncaught exception occurs, and then use forever
or upstart
Such a tool can restart (almost) instantly. Node.js will write the exception to STERR
so you can redirect the exception to a log file and get the error from it later. The disadvantage of this approach is that it does not provide an elegant way to handle temporary power outages or network errors if the error occurs outside of your code. scene. What a tool! — Restart the app and try again. If you combine this strategy with cluster module
, node can automatically restart any children that throw an error and print out the error. <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">var cluster = require(&#39;cluster&#39;);var workers = process.env.WORKERS || require(&#39;os&#39;).cpus().length;if (cluster.isMaster) {
console.log(&#39;start cluster with %s workers&#39;, workers); for (var i = 0; i < workers; ++i) { var worker = cluster.fork().process;
console.log(&#39;worker %s started.&#39;, worker.pid);
}
cluster.on(&#39;exit&#39;, function(worker) {
console.log(&#39;worker %s died. restart...&#39;, worker.process.pid);
cluster.fork();
});
} else { var http = require(&#39;http&#39;);
http.createServer(function (req, res) {
res.end("Look Mum! I&#39;m a server!\n");
}).listen(3000, "127.0.0.1");
}
process.on(&#39;uncaughtException&#39;, function (err) {
console.error((new Date).toUTCString() + &#39; uncaughtException:&#39;, err.message)
console.error(err.stack)
process.exit(1)
})</pre><div class="contentsignin">Copy after login</div></div>
7. Use the Domains
module [Translator’s Note: Now obsolete]
Domains
is An experimental feature added in the version, which makes exception handling more flexible and precise. The following is an example where the file does not exist. By using domains
, you can trigger an error event for a specific domain. You can also use different exception handling for different scenarios. This allows you to handle exceptions accordingly based on where they occur. If exiting a process is like cracking a nut with a hammer, this is like a precise scalpel giving you complete control over the program. <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">var domain = require(&#39;domain&#39;);var d = domain.create();var fs = require(&#39;fs&#39;);
d.on(&#39;error&#39;, function(err) {
console.error(err);
});
d.run(function() {
fs.readFile(&#39;somefile.txt&#39;, function (err, data) {
if (err) throw err;
console.log(data);
});
});</pre><div class="contentsignin">Copy after login</div></div><h3>8. 结论</h3>
<p>如果你在产品环境运行 Node.js 你起码应该对如何处理异常有一个想法。目前为止我相信当异常被抛出时,大多数人只是重启应用(也许是优雅地重启),<code>Domains
为应用提供了一种更聪明的面对异常的能力,异常处理器可能会选择简单的清理、关闭某些连接,最坏的情况下,退出进程。关键点就在于你有了选择。
我抛下榔头拾起手术刀的时候应该已经到了
The above is the detailed content of How to solve uncaught exceptions in Node.js. For more information, please follow other related articles on the PHP Chinese website!