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.