MCPcopy Create free account
hub / github.com/ChrisFeldmeier/OpenCodeRust / with_retry_and_hook

Function with_retry_and_hook

crates/opencode-provider/src/retry.rs:182–221  ·  view source on GitHub ↗

Same as [`with_retry`] but calls `hook(attempt, &error, delay_ms)` before each retry sleep, giving the caller a chance to log or update UI.

(
    config: &RetryConfig,
    mut f: F,
    mut hook: H,
)

Source from the content-addressed store, hash-verified

180/// Same as [`with_retry`] but calls `hook(attempt, &error, delay_ms)` before
181/// each retry sleep, giving the caller a chance to log or update UI.
182pub async fn with_retry_and_hook<F, Fut, T, E, H>(
183 config: &RetryConfig,
184 mut f: F,
185 mut hook: H,
186) -> Result<T, E>
187where
188 F: FnMut() -> Fut,
189 Fut: Future<Output = Result<T, E>>,
190 E: IsRetryable + std::fmt::Debug,
191 H: FnMut(u32, &E, u64),
192{
193 let mut attempt: u32 = 0;
194
195 loop {
196 attempt += 1;
197 match f().await {
198 Ok(val) => return Ok(val),
199 Err(e) => {
200 if attempt >= config.max_attempts {
201 return Err(e);
202 }
203 match e.is_retryable() {
204 Some(msg) => {
205 let delay_ms = delay(attempt, None);
206 hook(attempt, &e, delay_ms);
207 warn!(
208 attempt,
209 max = config.max_attempts,
210 delay_ms,
211 reason = %msg,
212 "retrying after transient error"
213 );
214 tokio::time::sleep(std::time::Duration::from_millis(delay_ms)).await;
215 }
216 None => return Err(e),
217 }
218 }
219 }
220 }
221}
222
223// ---------------------------------------------------------------------------
224// Tests

Callers

nothing calls this directly

Calls 3

sleepFunction · 0.85
is_retryableMethod · 0.80
delayFunction · 0.70

Tested by

no test coverage detected