Home >Web Front-end >JS Tutorial >Analyze the use of domain module in Node.js exception handling_node.js
NodeJS provides the domain module to simplify exception handling in asynchronous code. Before introducing this module, we need to first understand the concept of "domain". Simply put, a domain is a JS running environment. In a running environment, if an exception is not caught, it will be thrown as a global exception. NodeJS provides a method to capture global exceptions through the process object. The sample code is as follows
process.on('uncaughtException', function (err) { console.log('Error: %s', err.message); }); setTimeout(function (fn) { fn(); });
Error: undefined is not a function
Although global exceptions have a place to catch, for most exceptions, we hope to catch them as early as possible and decide the execution path of the code based on the results. We use the following HTTP server code as an example:
function async(request, callback) { // Do something. asyncA(request, function (err, data) { if (err) { callback(err); } else { // Do something asyncB(request, function (err, data) { if (err) { callback(err); } else { // Do something asyncC(request, function (err, data) { if (err) { callback(err); } else { // Do something callback(null, data); } }); } }); } }); } http.createServer(function (request, response) { async(request, function (err, data) { if (err) { response.writeHead(500); response.end(); } else { response.writeHead(200); response.end(data); } }); });
The above code hands the request object to the asynchronous function for processing, and then returns the response based on the processing result. Here we use a callback function to pass exceptions, so if there are a few more asynchronous function calls inside the async function, the code will look like the above. In order to make the code look better, we can use the domain module to create a subdomain (JS subruntime environment) every time a request is processed. Code running in a subdomain can throw exceptions at will, and these exceptions can be captured uniformly through the error event of the subdomain object. So the above code can be modified as follows:
function async(request, callback) { // Do something. asyncA(request, function (data) { // Do something asyncB(request, function (data) { // Do something asyncC(request, function (data) { // Do something callback(data); }); }); }); } http.createServer(function (request, response) { var d = domain.create(); d.on('error', function () { response.writeHead(500); response.end(); }); d.run(function () { async(request, function (data) { response.writeHead(200); response.end(data); }); }); });
As you can see, we use the .create method to create a subdomain object, and use the .run method to enter the entry point of the code that needs to be run in the subdomain. Since the asynchronous function callback function located in the subdomain no longer needs to catch exceptions, the code is suddenly much slimmer.
Trap
Whether a global exception is captured through the uncaughtException event of the process object, or a subdomain exception is captured through the error event of the subdomain object, the NodeJS official documentation strongly recommends restarting the program immediately after handling the exception, rather than letting the program Keep running. According to the official documentation, the program after an exception occurs is in an uncertain running state. If it does not exit immediately, the program may have a serious memory leak or behave strangely.
But some facts need to be clarified here. The throw..try..catch exception handling mechanism of JS itself will not cause memory leaks, nor will the execution results of the program be unexpected, but NodeJS is not pure JS. A large number of APIs in NodeJS are internally implemented in C/C++. Therefore, during the running of the NodeJS program, the code execution path shuttles between the inside and outside of the JS engine, and the exception throwing mechanism of JS may interrupt the normal code execution flow. This causes the code in the C/C++ part to behave abnormally, leading to memory leaks and other problems.
Therefore, use uncaughtException or domain to catch exceptions. When the code execution path involves C/C++ code, if you are not sure whether it will cause memory leaks and other problems, it is better to restart the program after handling the exception. When using the try statement to catch exceptions, generally the exceptions caught are JS's own exceptions, so there is no need to worry about appeals.