cockatiel
cockatiel copied to clipboard
`.execute` swallows the error?
Hi! I am likely doing something wrong, but nothing comes obvious from the docs, unfortunately.
This is what I do in the constructor:
this.retryPolicy = retry(
handleWhen((err) => !(err instanceof OptimisticLockError)),
{
maxAttempts: configService.get('RESILIENCY_MAX_RETRIES'),
backoff: new ExponentialBackoff(),
},
);
this.circuitBreaker = ctCircuitBreaker(handleAll, {
halfOpenAfter: configService.get('CIRCUIT_BREAKER_HALF_OPEN_AFTER'),
breaker: new ConsecutiveBreaker(
// +1 for the initial request. Has to be aligned with retries to get it working properly
configService.get('RESILIENCY_MAX_RETRIES') + 1,
),
});
this.resiliencePolicy = wrap(this.retryPolicy, this.circuitBreaker);
}
When I try to do:
public async flush() {
return await this.resiliencePolicy.execute(() =>
this.repository.getEntityManager().flush(),
);
The top level flush
function is not throwing, even though the this.repository.getEntityManager().flush()
is throwing, which results in completely bad behaviour of the app.
The error is basically swallowed by the execute
function.
The execute
will either return the successful result or propagate the last error the retryPolicy
encountered. If you want to observe errors thrown from the circuit breaker, or failures during the retry, you can use policy.onFailure
(docs)
I'm also not sure what the issue is here.
Does this.repository.getEntityManager().flush()
always throw? If so, I would expect that your flush
function also throws, either whatever is thrown by the inner flush
function, or a BrokenCircuitError
if the circuit breaker is open. If that doesn't happen, there might be a bug, but I doubt it.
If this.repository.getEntityManager().flush()
only throws sometimes, those errors might get swallowed by the retry policy, but that's by design.
Side note: In general, I would usually recommend to wrap retries and circuit breakers the other way round. After all, what’s the point of retrying if the underlying circuit breaker is open? Typically, you want to perform retries to recover from transient errors. Only if the errors turn out to not be transient (i.e., retries failed) and they are frequent enough, you want open the circuit breaker to give the failing system a chance to recover.
Haven't heard back from the reporter, going to close this issue.