fix(stripe): add request timeout to raw reqwest calls into Stripe API #104

Merged
YousifShkara merged 1 commit from fix/stripe-client-timeout into main 2026-06-11 05:17:36 +02:00
Owner

Closes BUNYIP-82.

Three reqwest::Client::new() call sites in crates/bunyip-domain/src/services/stripe.rs (webhook endpoint list / create / delete) had no timeout configured. Client::new() returns a client with no request, connect, or read timeout, so a hung Stripe upstream (network blip, regional outage, blackhole) blocks the awaiting actix worker indefinitely. A sufficiently long-lived stall can lock workers against a finite pool.

Replace the three sites with a single shared helper stripe_http_client() that builds a reqwest::Client with .timeout(Duration::from_secs(STRIPE_API_TIMEOUT_SECS)). Ten seconds is the ceiling for these webhook-endpoint CRUD calls; checkout / cancel flows run through the async-stripe client and inherit its own timeouts, so they are not touched. Adding the helper rather than inlining the builder keeps one source of truth for the value.

No behaviour change on the happy path. On a hung upstream, the call now returns reqwest::Error::is_timeout() == true within ten seconds instead of blocking the worker.

Pre-existing test_config_defaults flake on main is unrelated (parallel env-var race in config.rs:778); fmt + clippy + build clean.

#BUNYIP-82

Closes BUNYIP-82. Three `reqwest::Client::new()` call sites in `crates/bunyip-domain/src/services/stripe.rs` (webhook endpoint list / create / delete) had no timeout configured. `Client::new()` returns a client with no request, connect, or read timeout, so a hung Stripe upstream (network blip, regional outage, blackhole) blocks the awaiting actix worker indefinitely. A sufficiently long-lived stall can lock workers against a finite pool. Replace the three sites with a single shared helper `stripe_http_client()` that builds a `reqwest::Client` with `.timeout(Duration::from_secs(STRIPE_API_TIMEOUT_SECS))`. Ten seconds is the ceiling for these webhook-endpoint CRUD calls; checkout / cancel flows run through the async-stripe client and inherit its own timeouts, so they are not touched. Adding the helper rather than inlining the builder keeps one source of truth for the value. No behaviour change on the happy path. On a hung upstream, the call now returns `reqwest::Error::is_timeout() == true` within ten seconds instead of blocking the worker. Pre-existing `test_config_defaults` flake on main is unrelated (parallel env-var race in `config.rs:778`); fmt + clippy + build clean. #BUNYIP-82
fix(stripe): add request timeout to raw reqwest calls into Stripe API
All checks were successful
Create release / Create release from merged PR (pull_request) Has been skipped
Check / fmt / clippy / build / test (pull_request) Successful in 1m7s
5dea7f2bb5
Closes BUNYIP-82.

Three `reqwest::Client::new()` call sites in `crates/bunyip-domain/src/services/stripe.rs` (webhook endpoint list / create / delete) had no timeout configured. `Client::new()` returns a client with no request, connect, or read timeout, so a hung Stripe upstream (network blip, regional outage, blackhole) blocks the awaiting actix worker indefinitely. A sufficiently long-lived stall can lock workers against a finite pool.

Replace the three sites with a single shared helper `stripe_http_client()` that builds a `reqwest::Client` with `.timeout(Duration::from_secs(STRIPE_API_TIMEOUT_SECS))`. Ten seconds is the ceiling for these webhook-endpoint CRUD calls; checkout / cancel flows run through the async-stripe client and inherit its own timeouts, so they are not touched. Adding the helper rather than inlining the builder keeps one source of truth for the value.

No behaviour change on the happy path. On a hung upstream, the call now returns `reqwest::Error::is_timeout() == true` within ten seconds instead of blocking the worker.

Pre-existing `test_config_defaults` flake on main is unrelated (parallel env-var race in `config.rs:778`); fmt + clippy + build clean.

#BUNYIP-82
YousifShkara deleted branch fix/stripe-client-timeout 2026-06-11 05:17:36 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
psa-systems/bunyip!104
No description provided.