MCPcopy Index your code
hub / github.com/ChrisFeldmeier/OpenCodeRust / with_retry

Function with_retry

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

Retry an async operation up to `config.max_attempts` times. The closure `f` is called on each attempt. If it returns `Err(e)` and `e.is_retryable()` returns `Some(_)`, the helper sleeps for the computed delay and tries again. Otherwise the error is returned immediately.

(config: &RetryConfig, mut f: F)

Source from the content-addressed store, hash-verified

143/// `e.is_retryable()` returns `Some(_)`, the helper sleeps for the computed
144/// delay and tries again. Otherwise the error is returned immediately.
145pub async fn with_retry<F, Fut, T, E>(config: &RetryConfig, mut f: F) -> Result<T, E>
146where
147 F: FnMut() -> Fut,
148 Fut: Future<Output = Result<T, E>>,
149 E: IsRetryable + std::fmt::Debug,
150{
151 let mut attempt: u32 = 0;
152
153 loop {
154 attempt += 1;
155 match f().await {
156 Ok(val) => return Ok(val),
157 Err(e) => {
158 if attempt >= config.max_attempts {
159 return Err(e);
160 }
161 match e.is_retryable() {
162 Some(msg) => {
163 let delay_ms = delay(attempt, None);
164 warn!(
165 attempt,
166 max = config.max_attempts,
167 delay_ms,
168 reason = %msg,
169 "retrying after transient error"
170 );
171 tokio::time::sleep(std::time::Duration::from_millis(delay_ms)).await;
172 }
173 None => return Err(e),
174 }
175 }
176 }
177 }
178}
179
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.

Callers

nothing calls this directly

Calls 3

sleepFunction · 0.85
is_retryableMethod · 0.80
delayFunction · 0.70

Tested by

no test coverage detected