fix(account-snapshot): treat timeout/http5xx as transient fallback failures
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
co-authored by
genichin
parent
084e05a97d
commit
e3142017c9
@@ -75,10 +75,11 @@ def test_refresh_persists_independent_holdings_and_cash_capture_times():
|
|||||||
assert second.cash_captured_at == first.cash_captured_at
|
assert second.cash_captured_at == first.cash_captured_at
|
||||||
|
|
||||||
|
|
||||||
def test_sell_falls_back_only_for_transport_failure_and_within_sell_ttl():
|
@pytest.mark.parametrize("error_code", ["transport_failed", "timeout", "http_5xx"])
|
||||||
|
def test_sell_falls_back_for_transient_live_read_failures_within_sell_ttl(error_code):
|
||||||
broker, _, service, now = _wire()
|
broker, _, service, now = _wire()
|
||||||
assert service.refresh()
|
assert service.refresh()
|
||||||
broker.balance_error = "transport_failed"
|
broker.balance_error = error_code
|
||||||
now[0] += timedelta(seconds=601)
|
now[0] += timedelta(seconds=601)
|
||||||
|
|
||||||
assert service.holdings_for_sell() == [BalanceItem("005930", 2)]
|
assert service.holdings_for_sell() == [BalanceItem("005930", 2)]
|
||||||
@@ -126,6 +127,16 @@ def test_buy_guard_accounts_for_existing_pending_cash_and_never_renews_age():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("error_code", ["transport_failed", "timeout", "http_5xx"])
|
||||||
|
def test_buy_guard_keeps_existing_cash_snapshot_on_transient_cash_refresh_failure(error_code):
|
||||||
|
broker, _, service, _ = _wire()
|
||||||
|
assert service.refresh()
|
||||||
|
broker.cash_error = error_code
|
||||||
|
|
||||||
|
assert service.refresh() is False
|
||||||
|
assert service.buy_guard(qty=2, limit_price=100_000) is None
|
||||||
|
|
||||||
|
|
||||||
def test_current_account_hash_is_required_on_every_consume():
|
def test_current_account_hash_is_required_on_every_consume():
|
||||||
broker, _, service, _ = _wire()
|
broker, _, service, _ = _wire()
|
||||||
assert service.refresh()
|
assert service.refresh()
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ class AccountSnapshotService:
|
|||||||
try:
|
try:
|
||||||
return self._broker.get_balance()
|
return self._broker.get_balance()
|
||||||
except BrokerBalanceError as exc:
|
except BrokerBalanceError as exc:
|
||||||
if exc.code != "transport_failed":
|
if exc.code not in {"transport_failed", "timeout", "http_5xx"}:
|
||||||
raise AccountSnapshotUnavailable(
|
raise AccountSnapshotUnavailable(
|
||||||
"live_read_failed", detail_code=exc.code
|
"live_read_failed", detail_code=exc.code
|
||||||
) from None
|
) from None
|
||||||
@@ -253,7 +253,7 @@ class AccountSnapshotService:
|
|||||||
reserved_cash: float = 0.0,
|
reserved_cash: float = 0.0,
|
||||||
) -> Optional[str]:
|
) -> Optional[str]:
|
||||||
"""Return a stable rejection reason, or None when bounded admission passes."""
|
"""Return a stable rejection reason, or None when bounded admission passes."""
|
||||||
if self._last_cash_error not in {None, "transport_failed"}:
|
if self._last_cash_error not in {None, "transport_failed", "timeout", "http_5xx"}:
|
||||||
return "account_snapshot_unavailable"
|
return "account_snapshot_unavailable"
|
||||||
try:
|
try:
|
||||||
snapshot = self._load_current()
|
snapshot = self._load_current()
|
||||||
|
|||||||
Reference in New Issue
Block a user