-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Current behavior of the errorFilter option #564
Comments
this change was made intentionally. The thought was that if there is an error, but you have a error filter that passes, then that really isn't an error and the the fallback function shouldn't be called, which was happening before the change was made. The error should still be thrown if the error filter fails, if that doesn't happen, then there is a bug somewhere |
Hi, @lholmquist, thank you for replying quickly! In my case, I don't have a fallback function. I used to use the filterError only to ignore some errors and don't consider them to open the circuit. But still, I depend on these errors being exposed by the fire method to take the correct actions out of the circuit breaker logic. Do you have any suggestions on how I could keep this behavior? |
I'm not clear on what you mean by "these errors being exposed by the fire method". You do still have access to the errors themselves in your You also receive these errors when listening for Would it help for the resolved promise to contain both a truthy value, and the caught exceptions? E.g. function handleError (error, circuit, timeout, args, latency, resolve, reject) {
let errorFiltered;
if ((errorFiltered = circuit.options.errorFilter(error, ...args))) {
circuit.emit('success', error, latency);
// Provide the error
resolve({ err: error, filtered: errorFiltered});
}
// ... etc
} |
Hi, @lance, thank you for your reply! What I meant was related to the fire function. In the previous release, this code:
resulted in the Right now we have the Using your suggestion, to be able to get the error using the returned promise by the fire function, and treat this as an error outside of the circuit breaker logic, I should do something like this:
Is it right? I couldn't analyze the code deeply, but it seems we are increasing the responsibility of the Does the purpose of the |
I see your point @mNalon... @lholmquist in #540 the issue was that the fallback function was being called even when the error filter was applied and the error was filtered. The change in #556 correctly addressed this by eliminating that call. But it also changed the logic of resolve/reject for these errors. Now, if an error is filtered, it's always resolved. Whereas before, it was almost always rejected. It only resolved when the fallback function was called and was successful. This is tricky logic because of all the possible cases. I am leaning towards saying the change in #556 was in error regarding promise resolution. I propose we consider modifying the function handleError (error, circuit, timeout, args, latency, resolve, reject) {
clearTimeout(timeout);
let errorFiltered;
if ((errorFiltered = circuit.options.errorFilter(error, ...args))) {
circuit.emit('success', error, latency);
} else {
fail(circuit, error, args, latency);
// Only call the fallback function if there errorFilter doesn't succeed
const fb = fallback(circuit, error, args);
if (fb) resolve(fb);
return;
}
reject(error);
} And then quickly release a 6.1.0. What do you think? |
It seems a little weird that we would emit a success, but also return a rejected promise.
I'm also sort of confused by this statement. If you aren't treating this as an error in the CB logic, then why would you need to treat it as an error outside the CB logic? Maybe using the error filter isn't the right approach here? 🤷 |
It does, I agree. But let me try and explain the thinking. The Lines 655 to 667 in 1a3b0b4
|
This commit reverts some of the behavior changes in nodeshift#556. In that PR, the intent was to avoid calling the fallback function when an an invocation error is filtered by a user supplied `errorFilter` function. It did accomplish that, however, it also changed how a function resolves in the case of a filtered error. Previously, even though the error was filtered, the function invocation would return the error to the caller. With nodeshift#556, this changed so that the caller instead receives simply a truthy value. This commit reverts that behavior so that the error is returned. While it may seem counter intuitive to return an error when the it was filtered by a user supplied `errorFilter` function, there are good reasons to do so. It provides the caller with error information at the point of invocation instead of in an event listener which may be disconnected from the invocation code path. The purpose of `errorFilter` is simply to prevent filtered errors from causing the circuit to open. But the fact is that the function invocation failed, and providing this to the user at the point of failure is better usability in my opinion. Plus, it's what we've always been doing, and I think the change to returning a truthy value was really just a side effect of not calling the fallback function. My preference would be to minimize the breaking changes in 6.x, and this PR helps to accomplish that (albeit 6.0 will be a weird bump in the road). Fixes: nodeshift#564 Signed-off-by: Lance Ball <lball@redhat.com>
This commit reverts some of the behavior changes in #556. In that PR, the intent was to avoid calling the fallback function when an an invocation error is filtered by a user supplied `errorFilter` function. It did accomplish that, however, it also changed how a function resolves in the case of a filtered error. Previously, even though the error was filtered, the function invocation would return the error to the caller. With #556, this changed so that the caller instead receives simply a truthy value. This commit reverts that behavior so that the error is returned. While it may seem counter intuitive to return an error when the it was filtered by a user supplied `errorFilter` function, there are good reasons to do so. It provides the caller with error information at the point of invocation instead of in an event listener which may be disconnected from the invocation code path. The purpose of `errorFilter` is simply to prevent filtered errors from causing the circuit to open. But the fact is that the function invocation failed, and providing this to the user at the point of failure is better usability in my opinion. Plus, it's what we've always been doing, and I think the change to returning a truthy value was really just a side effect of not calling the fallback function. My preference would be to minimize the breaking changes in 6.x, and this PR helps to accomplish that (albeit 6.0 will be a weird bump in the road). Fixes: #564 Signed-off-by: Lance Ball <lball@redhat.com>
released as 6.0.1 |
Node.js Version:
v12.21.0
Operating System:
macOS
Steps to Produce Error:
In the last release, when I have an action that returns a rejected promise with an error that I want to filter, the output of the fire method becomes a resolved promise with the truthy value returned by the errorFilter callback option. Is this intentional?
I believe this is happening because of the change added by this line
opossum/lib/circuit.js
Line 661 in 7a920bf
If this change was intentional, how can I get the error thrown by the action in the case of an error that is being filtered by the errorFilter?
The text was updated successfully, but these errors were encountered: