Handle error thrown by fact
robross0606 opened this issue · 4 comments
I'm trying to figure out what the Engine does it a Fact function throws an exception. As far as I can tell, there is no event handler for this and it doesn't return the error as the Fact value or anything like that. It also doesn't seem to be caught by either of the existing success
or failure
events. Is this supported in some way or does the entire engine.run()
bomb out?
I have just found that a fact throwing an error will kick back from engine.run()
:
try {
await engine.run()
} catch (error) {
engine.stop()
}
However, the remaining rule facts somehow continue to execute on the node.js process loop outside the await
used in the try/catch
block. Calling engine.stop()
does not stop that execution thought it does set the status
of that RULE to 'FINISHED'
. Nevertheless, I've found via Jest spy that fact execution seems to continue even after.
Is there any way to prevent this short of never throwing an exception from a fact?
Turns out the engine
keeps a factResultCache
on the almanac
that has all the promises on it. There are indeed some that are "pending" even after the engine is closed in an error situation. I was able to work around the problem with a special error type which includes the almanac
on the thrown error:
if (error.almanac) {
// Resolve remaining fact cache to prevent continuing async execution
await Promise.allSettled(error.almanac.factResultsCache.values())
}
This is effectively a process/memory leak. Can this be included in Milestone 7?
Another potentially useful feature here would be to have an event handler for "error":
engine.on('error', (event, almanac, error) => {
// TODO: Handle errors thrown by facts
})