feat: Improve blocking API safety, HTTP reliability, and batch error reporting#5
Conversation
…reporting Refactor the blocking API to use a multi-threaded runtime and return `Result` for safer, non-panicking error handling outside async contexts. Enhance HTTP client robustness with idempotent retry logic, jittered backoff, and correct `GET` requests for workspace metadata and configuration. Introduce `PartialFailure` error for chunked batch operations to report successfully processed items. Centralize search parameter validation and query parameter generation.
There was a problem hiding this comment.
Sorry @leszek3737, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
There was a problem hiding this comment.
Code Review
This pull request refactors the blocking client to return Results instead of panicking when called within an async runtime, configures a multi-threaded runtime, and restricts HTTP retries to idempotent methods. It also updates workspace queries to use GET requests instead of POST, introduces jittered backoff delays, and consolidates search parameter validation. Feedback on these changes highlights that using .ok().flatten() in the blocking iterator silently discards runtime configuration errors, and warns that the new jitter logic using entropy % 500 on sub-second nanoseconds may fail on platforms with coarse clock resolutions, suggesting an entropy scrambling step to ensure uniform distribution.
Greptile SummaryThis PR makes the blocking API non-panicking by having
Confidence Score: 4/5Safe to merge; all behavioural changes are intentional and well-tested. The three findings are non-blocking quality issues. The core changes are solid: the blocking runtime guard, idempotent-only retry logic, correct GET for workspace reads, and PartialFailure batch reporting all work as described. The three findings are cosmetic or edge-case: the Iterator silent-None issue is a trait constraint, the search_max_distance label in a conclusion builder error message is misleading, and the jitter constant fallback on a backwards clock is a corner case on unusual hardware. None affect the happy path or data correctness. src/blocking/iter.rs and src/conclusion.rs are worth a second look before merge. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[blocking API call] --> B{block_on}
B --> C{Handle::try_current?}
C -- "Ok: inside async runtime" --> D["Err(Configuration)"]
D --> E[caller gets Err propagated via ?]
C -- "Err: no active runtime" --> F[multi-thread runtime.block_on future]
F --> G["Ok(async result)"]
G --> H[caller unwraps with ?]
H --> I{HTTP request}
I --> J{response ok?}
J -- "yes" --> K[return result]
J -- "no" --> L{is_idempotent AND retryable status?}
L -- "yes" --> M[jittered_delay then retry]
M --> I
L -- "no POST/PATCH" --> N[return Err immediately]
L -- "idempotent, non-retryable" --> N
subgraph BlockingIter
O[Iterator::next] --> P{block_on StreamNext}
P -- "Ok(Some item)" --> Q[yield item]
P -- "Ok(None)" --> R[end of stream]
P -- "Err runtime guard" --> S["None - silent stop"]
end
|
… errors - blocking/iter: replace silent .ok().flatten() with .expect() to surface async-runtime misconfiguration instead of silently ending the iterator - http/client: add LCG scrambling to jitter entropy to handle coarse clock resolutions (Windows/VMs), and use unwrap_or_else to avoid pinning entropy to 0 when system clock is before Unix epoch - conclusion: remap 'search_max_distance' to 'distance' in QueryConclusionsBuilder validation errors so the field name matches the builder's public API
Refactor the blocking API to use a multi-threaded runtime and return
Resultfor safer, non-panicking error handling outside async contexts. Enhance HTTP client robustness with idempotent retry logic, jittered backoff, and correctGETrequests for workspace metadata and configuration. IntroducePartialFailureerror for chunked batch operations to report successfully processed items. Centralize search parameter validation and query parameter generation.