_exceptions.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. from __future__ import annotations
  2. import sys
  3. from collections.abc import Generator
  4. from textwrap import dedent
  5. from typing import Any
  6. if sys.version_info < (3, 11):
  7. from exceptiongroup import BaseExceptionGroup
  8. class BrokenResourceError(Exception):
  9. """
  10. Raised when trying to use a resource that has been rendered unusable due to external
  11. causes (e.g. a send stream whose peer has disconnected).
  12. """
  13. class BrokenWorkerProcess(Exception):
  14. """
  15. Raised by :meth:`~anyio.to_process.run_sync` if the worker process terminates abruptly or
  16. otherwise misbehaves.
  17. """
  18. class BrokenWorkerInterpreter(Exception):
  19. """
  20. Raised by :meth:`~anyio.to_interpreter.run_sync` if an unexpected exception is
  21. raised in the subinterpreter.
  22. """
  23. def __init__(self, excinfo: Any):
  24. # This was adapted from concurrent.futures.interpreter.ExecutionFailed
  25. msg = excinfo.formatted
  26. if not msg:
  27. if excinfo.type and excinfo.msg:
  28. msg = f"{excinfo.type.__name__}: {excinfo.msg}"
  29. else:
  30. msg = excinfo.type.__name__ or excinfo.msg
  31. super().__init__(msg)
  32. self.excinfo = excinfo
  33. def __str__(self) -> str:
  34. try:
  35. formatted = self.excinfo.errdisplay
  36. except Exception:
  37. return super().__str__()
  38. else:
  39. return dedent(
  40. f"""
  41. {super().__str__()}
  42. Uncaught in the interpreter:
  43. {formatted}
  44. """.strip()
  45. )
  46. class BusyResourceError(Exception):
  47. """
  48. Raised when two tasks are trying to read from or write to the same resource
  49. concurrently.
  50. """
  51. def __init__(self, action: str):
  52. super().__init__(f"Another task is already {action} this resource")
  53. class ClosedResourceError(Exception):
  54. """Raised when trying to use a resource that has been closed."""
  55. class ConnectionFailed(OSError):
  56. """
  57. Raised when a connection attempt fails.
  58. .. note:: This class inherits from :exc:`OSError` for backwards compatibility.
  59. """
  60. def iterate_exceptions(
  61. exception: BaseException,
  62. ) -> Generator[BaseException, None, None]:
  63. if isinstance(exception, BaseExceptionGroup):
  64. for exc in exception.exceptions:
  65. yield from iterate_exceptions(exc)
  66. else:
  67. yield exception
  68. class DelimiterNotFound(Exception):
  69. """
  70. Raised during
  71. :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the
  72. maximum number of bytes has been read without the delimiter being found.
  73. """
  74. def __init__(self, max_bytes: int) -> None:
  75. super().__init__(
  76. f"The delimiter was not found among the first {max_bytes} bytes"
  77. )
  78. class EndOfStream(Exception):
  79. """
  80. Raised when trying to read from a stream that has been closed from the other end.
  81. """
  82. class IncompleteRead(Exception):
  83. """
  84. Raised during
  85. :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_exactly` or
  86. :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the
  87. connection is closed before the requested amount of bytes has been read.
  88. """
  89. def __init__(self) -> None:
  90. super().__init__(
  91. "The stream was closed before the read operation could be completed"
  92. )
  93. class TypedAttributeLookupError(LookupError):
  94. """
  95. Raised by :meth:`~anyio.TypedAttributeProvider.extra` when the given typed attribute
  96. is not found and no default value has been given.
  97. """
  98. class WouldBlock(Exception):
  99. """Raised by ``X_nowait`` functions if ``X()`` would block."""
  100. class NoEventLoopError(RuntimeError):
  101. """
  102. Raised by several functions that require an event loop to be running in the current
  103. thread when there is no running event loop.
  104. This is also raised by :func:`.from_thread.run` and :func:`.from_thread.run_sync`
  105. if not calling from an AnyIO worker thread, and no ``token`` was passed.
  106. """
  107. class RunFinishedError(RuntimeError):
  108. """
  109. Raised by :func:`.from_thread.run` and :func:`.from_thread.run_sync` if the event
  110. loop associated with the explicitly passed token has already finished.
  111. """
  112. def __init__(self) -> None:
  113. super().__init__(
  114. "The event loop associated with the given token has already finished"
  115. )
  116. class TaskFailed(Exception):
  117. """
  118. Raised when awaiting on, or attempting to access the return value of, a
  119. :class:`.TaskHandle` that raised an exception.
  120. """
  121. class TaskCancelled(TaskFailed):
  122. """
  123. Raised when awaiting on, or attempting to access the return value of, a
  124. :class:`.TaskHandle` that was cancelled.
  125. """
  126. class TaskNotFinished(Exception):
  127. """
  128. Raised when attempting to access the return value or exception of a
  129. :class:`.TaskHandle` that is still pending completion.
  130. """