I have a domain exception handler (wrapper for nightwatch tests).
my exception handler wrapper
var domainError = function(func) {
return function() {
var d = domain.create().on('error', function(err) {
console.error(err.stack);
});
d.enter();
try {
return func.apply(this, arguments);
}
catch (err) {
//do something with the err
}
d.exit();
}
};
I am trying to set timeouts so that return func.apply(this, arguments);
doesn't take forever.
Could anyone suggest how I can add timeouts and make the domain end the function and exit, if it exceeds timeout?
This is due to when a function is executed as a parameter to setTimeout , the execution context is different to the execution context of the function! Now this will print out undefined because the this keyword is executed in the context of the setTimeout function and is therefore not defined.
For example, if you want to set request timeout to 200 seconds, then add the following line to server. js above. res. setTimeout(200);
In Node. js, default server timeout is 0 milliseconds for the latest version and 2min i.e. (120000 milliseconds) for the older version.
The setTimeout function is used to call a function after the specified number of milliseconds. The delay of the called function begins after the remaining statements in the script have finished executing. The setTimeout function is found in the Timers module of Node. js.
This is impossible in Node's concurrency model. There are no "interrupts" - multiprocessing is done cooperatively. If you look at it from the other side - you get a really powerful guarantee that your code will almost always run to completion.
You can spawn another child process and then preempt that (since processes support preemption).
The easiest way to terminate a synchronous function is to execute it in its own "isolate" - meaning it can be killed. Note that this is not as performant as making a dedicated worker "process" and using async io to communicate with it - which is probably faster - but this is easier.
var vm = require('vm'); // get the VM module
// when you want to run a bit
function withError(func, context, timeout){
var ctx = vm.createContext(context);
var code = func.toString().slice(12).slice(0,-2)
return vm.runInContext(code, ctx, {
timeout: timeout,
displayErrors: true; // to log, like in your version
});
}
Note that this code means the function has no access to closure scope or arguments, so everything needs to be in its scope - it's not as big of an issue as you might think since you can convert:
function doFoo(x, y){
return x + y + z; // z is from closure
}
Into
function doFoo(){
return this.x + this.y + this.z;
}
And call it as
withError(doFoo, {x:x, y:y, z:z }, 2000); // 2000 ms timeout
This can also be better automated by using a lexical analysis tool that generates a syntax tree.
If I may suggest an alternative - write your func
in a way that it can yield control - cooperative multitasking is a lot easier and less error prone in these cases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With