Resolve the use of the domain module in Node. js Exception Handling, node. jsdomain
NodeJS provides the domain module to simplify Exception Handling for asynchronous code. Before introducing this module, we need to first understand the concept of "domain. Simply put, a domain is a JS runtime environment. In a runtime environment, if an exception is not caught, it will be thrown as a global exception. NodeJS uses the process object to capture global exceptions. 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 can be captured, we hope to capture most exceptions as soon as possible and determine the code execution path based on the results. The following HTTP server code is used 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 submits the request object to the asynchronous function for processing, and then returns a response based on the processing result. Here we use the callback function to pass exceptions. Therefore, if there are more asynchronous function calls in the async function, the code will look like the above. To make the Code look better, we can use the domain module to create a subdomain (JS subruntime environment) every time we process a request ). Code running in a subdomain can throw exceptions at will, which can be captured by the error event of the subdomain object. The above code can be transformed 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); }); });});
We can see that we have created a subdomain object using the. create method, and enter the entry point of the Code to be run in the subdomain through the. run method. The asynchronous function callback function in the subdomain does not need to capture exceptions any more, and the code is much reduced.
Traps
Whether the global exception is captured through the uncaughtException event of the process object or the subdomain exception is captured through the error event of the subdomain object, in the official NodeJS documentation, we strongly recommend that you restart the program immediately after handling the exception, instead of continuing to run the program. According to the official documentation, the program is in an uncertain running state after an exception occurs. If you do not exit immediately, the program may have a serious memory leak, which may be very strange.
However, some facts need to be clarified here. JS's throw... try... catch exception handling mechanism does not cause memory leakage or unexpected execution results, but NodeJS is not a pure JS. A large number of APIs in NodeJS are implemented using C/C ++ internally. Therefore, the Code Execution path shuttles through the internal and external interfaces of the JS engine during the running of the NodeJS program, JS exception throws may interrupt normal code execution processes, leading to exceptions in C/C ++ code and Memory leakage.
Therefore, when uncaughtException or domain is used to capture exceptions and code in C/C ++ is involved in the Code Execution path, if you are not sure whether it will cause problems such as memory leakage, it is better to restart the program after handling the exception. When a try statement is used to catch exceptions, JS exceptions are usually caught, so you don't have to worry about appeal.