Skip to content

Frontend-safe SP API timeouts + graceful add-to-cart degradation (#306) - #308

Open
chrismshea wants to merge 1 commit into
mainfrom
306-frontend-api-timeout-hardening
Open

Frontend-safe SP API timeouts + graceful add-to-cart degradation (#306)#308
chrismshea wants to merge 1 commit into
mainfrom
306-frontend-api-timeout-hardening

Conversation

@chrismshea

Copy link
Copy Markdown

Summary

Hardens the storefront against a slow or unreachable Subscribe Pro API. The SP API is called synchronously during add-to-cart for subscription-enabled products; with the SDK default of 30s and no connect timeout, a slow/unreachable API can tie up PHP-FPM workers under load and degrade the storefront.

This PR (1) makes the frontend API timeouts configurable with frontend-safe defaults, and (2) closes a gap where a timeout in the add-to-cart path could bubble up uncaught.

Changes

  • Two new Advanced config fields (per-website overridable), under Stores → Config → Subscribe Pro → Advanced:
    • API Request Timeout (default 5s) — total request timeout.
    • API Connect Timeout (default 2s) — connection timeout; 0 disables the separate connect timeout.
  • Model/Config/Advanced.phpgetApiRequestTimeout() / getApiConnectTimeout() getters.
  • Platform/Platform.php — injects Model/Config/Advanced and plumbs both timeouts into the SDK config (api_request_timeout / connect_timeout), only overriding when the configured value is > 0 (a blank/zero value falls back to the SDK default).
  • Observer/CheckoutCart/AddProductToCartAfter.php — now also catches GuzzleHttp\Exception\TransferException. A Guzzle connect/request timeout is not response-based, so it is not a SubscribePro\Exception\HttpException and was previously not caught; it now degrades gracefully (item added without subscription options) instead of bubbling.

Why the extra catch

SubscribePro\Exception\HttpException requires a ResponseInterface (only thrown on a 4xx/5xx). A timeout / unreachable host raises GuzzleHttp\Exception\ConnectException / RequestException (both extend TransferException) before any response exists, so catch (HttpException) does not catch it. Verified against a blackhole API: the old catch set let the exception bubble uncaught; the new TransferException catch degrades gracefully.

Dependency

Requires subscribepro/subscribepro-php#57 (adds the connect_timeout SDK config key). The api_request_timeout change works with the current SDK; connect_timeout is a no-op until the SDK PR is merged and the dependency is bumped.

Testing

Verified in a Magento 2.4.8 / PHP 8.3 environment:

  • DI resolves Platform with the new Advanced dependency; config defaults flow through to a built SDK (Http receives requestTimeout=5, connectTimeout=2).
  • Blackhole API + short timeout: connect timeout fires at ~1.0s; old catch set bubbled uncaught, new catch set degrades gracefully.
  • Storefront, admin, and the SP Advanced config page all render (HTTP 200); no exception-log noise.

Scope / follow-up

This PR covers the add-to-cart path (the highest-risk hot path). Extending graceful degradation to the remaining synchronous storefront call sites is tracked separately in #307 (with a design-led, choke-point approach rather than per-site try/catch).

Notes

  • Timeout defaults (5s/2s) are intentionally exposed as config; tune per environment based on observed API latency.
  • Backward compatible: leaving the fields blank/zero falls back to prior SDK behavior.

Closes #306

The SP API is called synchronously during add-to-cart for subscription-
enabled products. With the SDK default of 30s and no connect timeout, a
slow or unreachable API can tie up PHP workers under load and degrade the
storefront.

Changes:
- Add two Advanced config fields: 'API Request Timeout' (default 5s) and
  'API Connect Timeout' (default 2s), per-website overridable.
- Plumb these through Platform::createSdk into the SDK config
  (api_request_timeout / connect_timeout), only overriding when > 0 so a
  blank value falls back to the SDK default.
- Widen AddProductToCartAfter to catch GuzzleHttp TransferException
  (connect/request timeouts are not response-based, so they are not
  SubscribePro HttpExceptions) and degrade gracefully instead of bubbling.

Requires subscribepro/subscribepro-php#56 for connect_timeout support.
Refs #306
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Lower default SP API timeout for frontend calls; support connect timeout

1 participant