1from __future__ import annotations
2
3import sys
4from collections.abc import Generator
5
6if sys.version_info < (3, 11):
7 from exceptiongroup import BaseExceptionGroup
8
9
10class BrokenResourceError(Exception):
11 """
12 Raised when trying to use a resource that has been rendered unusable due to external
13 causes (e.g. a send stream whose peer has disconnected).
14 """
15
16
17class BrokenWorkerProcess(Exception):
18 """
19 Raised by :func:`run_sync_in_process` if the worker process terminates abruptly or
20 otherwise misbehaves.
21 """
22
23
24class BusyResourceError(Exception):
25 """
26 Raised when two tasks are trying to read from or write to the same resource
27 concurrently.
28 """
29
30 def __init__(self, action: str):
31 super().__init__(f"Another task is already {action} this resource")
32
33
34class ClosedResourceError(Exception):
35 """Raised when trying to use a resource that has been closed."""
36
37
38class DelimiterNotFound(Exception):
39 """
40 Raised during
41 :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the
42 maximum number of bytes has been read without the delimiter being found.
43 """
44
45 def __init__(self, max_bytes: int) -> None:
46 super().__init__(
47 f"The delimiter was not found among the first {max_bytes} bytes"
48 )
49
50
51class EndOfStream(Exception):
52 """
53 Raised when trying to read from a stream that has been closed from the other end.
54 """
55
56
57class IncompleteRead(Exception):
58 """
59 Raised during
60 :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_exactly` or
61 :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the
62 connection is closed before the requested amount of bytes has been read.
63 """
64
65 def __init__(self) -> None:
66 super().__init__(
67 "The stream was closed before the read operation could be completed"
68 )
69
70
71class TypedAttributeLookupError(LookupError):
72 """
73 Raised by :meth:`~anyio.TypedAttributeProvider.extra` when the given typed attribute
74 is not found and no default value has been given.
75 """
76
77
78class WouldBlock(Exception):
79 """Raised by ``X_nowait`` functions if ``X()`` would block."""
80
81
82def iterate_exceptions(
83 exception: BaseException,
84) -> Generator[BaseException, None, None]:
85 if isinstance(exception, BaseExceptionGroup):
86 for exc in exception.exceptions:
87 yield from iterate_exceptions(exc)
88 else:
89 yield exception