Files
wehub-resource-sync 5296d0e97c
CI / Ban suppressions and legacy annotations (push) Has been cancelled
CI / pytest (push) Has been cancelled
CI / ruff-check (push) Has been cancelled
CI / ruff-format (push) Has been cancelled
CI / ty (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:35:44 +08:00

113 lines
2.9 KiB
Python

"""Canonical, protocol-neutral execution failure contracts."""
from dataclasses import FrozenInstanceError, fields, is_dataclass
import pytest
from free_claude_code.core.failures import (
ExecutionFailure,
FailureKind,
find_execution_failure,
)
def test_failure_kind_has_only_protocol_neutral_semantics() -> None:
assert tuple(FailureKind) == (
FailureKind.INVALID_REQUEST,
FailureKind.AUTHENTICATION,
FailureKind.PERMISSION,
FailureKind.RATE_LIMIT,
FailureKind.OVERLOADED,
FailureKind.TIMEOUT,
FailureKind.UPSTREAM,
FailureKind.UNAVAILABLE,
)
assert tuple(kind.value for kind in FailureKind) == (
"invalid_request",
"authentication",
"permission",
"rate_limit",
"overloaded",
"timeout",
"upstream",
"unavailable",
)
def test_execution_failure_is_the_direct_frozen_slotted_exception() -> None:
failure = ExecutionFailure(
kind=FailureKind.RATE_LIMIT,
status_code=429,
message="Provider rate limit reached.",
retryable=True,
)
assert is_dataclass(failure)
assert tuple(field.name for field in fields(failure)) == (
"kind",
"status_code",
"message",
"retryable",
)
assert ExecutionFailure.__slots__ == (
"kind",
"status_code",
"message",
"retryable",
)
assert str(failure) == "Provider rate limit reached."
assert failure.args == ("Provider rate limit reached.",)
with pytest.raises(ExecutionFailure) as raised:
raise failure
assert raised.value is failure
with pytest.raises(FrozenInstanceError):
failure.status_code = 500
def test_execution_failure_uses_exception_identity_not_value_equality() -> None:
first = ExecutionFailure(
kind=FailureKind.UPSTREAM,
status_code=500,
message="same",
retryable=True,
)
second = ExecutionFailure(
kind=FailureKind.UPSTREAM,
status_code=500,
message="same",
retryable=True,
)
assert first is not second
assert first != second
def test_find_execution_failure_recurses_through_nested_groups() -> None:
failure = ExecutionFailure(
kind=FailureKind.RATE_LIMIT,
status_code=429,
message="provider is busy",
retryable=True,
)
grouped = ExceptionGroup(
"stream and cleanup failed",
[
RuntimeError("cleanup failed"),
ExceptionGroup("provider failed", [failure]),
],
)
assert find_execution_failure(failure) is failure
assert find_execution_failure(grouped) is failure
def test_find_execution_failure_leaves_unrelated_groups_unclassified() -> None:
grouped = BaseExceptionGroup(
"unrelated failures",
[RuntimeError("socket closed"), KeyboardInterrupt()],
)
assert find_execution_failure(grouped) is None