Commit 542770b
authored
feat: [CHA-2958] error hierarchy + wait_for_task (#261)
* feat: standardized error hierarchy + wait_for_task (CHA-2958)
Adds StreamException / StreamApiException / StreamRateLimitException /
StreamTransportException / StreamTaskException per the Server-Side SDK
Error Handling Spec §9.2. APIError envelope parsing now surfaces
unrecoverable, exception_fields, more_info, details, and the raw body on
the new StreamApiException class. 429s build StreamRateLimitException
with retry_after parsed from Retry-After (RFC 7231 §7.1.3 — integer
seconds or HTTP-date, past dates clamp to zero, missing/garbage → None).
httpx.RequestError raised by the sync and async transport paths is
wrapped into StreamTransportException with an error_type enum
(connection_reset / timeout / dns_failure / tls_handshake_failed /
unknown) and the original exception preserved via __cause__. The
classifier walks __cause__/__context__ to detect ssl.SSLError and
socket.gaierror that httpx hides one level down.
Adds Stream.wait_for_task and AsyncStream.wait_for_task that poll
get_task until terminal state. Failed tasks raise StreamTaskException
populated from ErrorResult; timeouts raise StreamTransportException with
error_type='timeout'.
getstream.base.StreamAPIException (capital API) is now an alias for the
new StreamApiException via a module-level __getattr__ that emits
DeprecationWarning. The alias points at the same class object, so
isinstance / except / pytest.raises keep working without changes; it
will be removed one minor cycle after this release.
* test: replace mocks in test_exceptions.py with real HTTP server + sockets
Honors AGENTS.md "do not use mocks or mock things in general unless you
are asked to do that directly" (also flagged by CodeRabbit on PR #261).
Two transport-wrapping tests previously used httpx.MockTransport. They
now drive real httpx errors:
- Connection-refused goes via a freshly-bound-and-closed loopback port.
- Read-timeout goes via a real pytest-httpserver instance that sleeps
past the client's request_timeout.
Six wait_for_task tests previously used _Fake* stand-in client + response
classes. They now point a real Stream/AsyncStream client at a pytest-
httpserver that returns get-task JSON in the real wire format
(nanosecond-epoch created_at/updated_at, ErrorResult payload).
Adds pytest-httpserver as a dev dependency.
* docs(py): drop spec § refs and mechanism prose from error-handling docstrings1 parent 35e84b0 commit 542770b
9 files changed
Lines changed: 1211 additions & 63 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
12 | 40 | | |
13 | 41 | | |
14 | 42 | | |
| |||
45 | 73 | | |
46 | 74 | | |
47 | 75 | | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
48 | 81 | | |
49 | 82 | | |
50 | 83 | | |
51 | 84 | | |
52 | 85 | | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
53 | 95 | | |
54 | 96 | | |
55 | 97 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
1 | 8 | | |
2 | 9 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
10 | | - | |
11 | | - | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
12 | 16 | | |
13 | 17 | | |
14 | 18 | | |
| |||
102 | 106 | | |
103 | 107 | | |
104 | 108 | | |
105 | | - | |
106 | | - | |
107 | | - | |
| 109 | + | |
108 | 110 | | |
109 | 111 | | |
110 | 112 | | |
| |||
118 | 120 | | |
119 | 121 | | |
120 | 122 | | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
| 123 | + | |
| 124 | + | |
125 | 125 | | |
126 | 126 | | |
127 | 127 | | |
| |||
291 | 291 | | |
292 | 292 | | |
293 | 293 | | |
294 | | - | |
295 | | - | |
296 | | - | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
297 | 300 | | |
298 | 301 | | |
299 | 302 | | |
| |||
604 | 607 | | |
605 | 608 | | |
606 | 609 | | |
607 | | - | |
608 | | - | |
609 | | - | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
610 | 616 | | |
611 | 617 | | |
612 | 618 | | |
| |||
721 | 727 | | |
722 | 728 | | |
723 | 729 | | |
724 | | - | |
725 | | - | |
726 | | - | |
727 | | - | |
728 | | - | |
729 | | - | |
730 | | - | |
731 | | - | |
732 | | - | |
733 | | - | |
734 | | - | |
735 | | - | |
736 | | - | |
737 | | - | |
738 | | - | |
739 | | - | |
740 | | - | |
741 | | - | |
742 | | - | |
743 | | - | |
744 | | - | |
745 | | - | |
746 | | - | |
747 | | - | |
748 | | - | |
749 | | - | |
750 | | - | |
751 | | - | |
752 | | - | |
753 | | - | |
754 | | - | |
755 | | - | |
756 | | - | |
757 | | - | |
758 | | - | |
759 | | - | |
760 | | - | |
761 | | - | |
762 | | - | |
763 | | - | |
764 | | - | |
765 | | - | |
766 | | - | |
767 | | - | |
768 | | - | |
769 | | - | |
770 | | - | |
771 | | - | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
772 | 743 | | |
773 | 744 | | |
774 | 745 | | |
| |||
0 commit comments