Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Exceptions and errors for use in twisted.internet modules.
  5. """
  6. import socket
  7. from incremental import Version
  8. from twisted.python import deprecate
  9. class BindError(Exception):
  10. __doc__ = MESSAGE = "An error occurred binding to an interface"
  11. def __str__(self) -> str:
  12. s = self.MESSAGE
  13. if self.args:
  14. s = "{}: {}".format(s, " ".join(self.args))
  15. s = "%s." % s
  16. return s
  17. class CannotListenError(BindError):
  18. """
  19. This gets raised by a call to startListening, when the object cannotstart
  20. listening.
  21. @ivar interface: the interface I tried to listen on
  22. @ivar port: the port I tried to listen on
  23. @ivar socketError: the exception I got when I tried to listen
  24. @type socketError: L{socket.error}
  25. """
  26. def __init__(self, interface, port, socketError):
  27. BindError.__init__(self, interface, port, socketError)
  28. self.interface = interface
  29. self.port = port
  30. self.socketError = socketError
  31. def __str__(self) -> str:
  32. iface = self.interface or "any"
  33. return "Couldn't listen on {}:{}: {}.".format(
  34. iface, self.port, self.socketError
  35. )
  36. class MulticastJoinError(Exception):
  37. """
  38. An attempt to join a multicast group failed.
  39. """
  40. class MessageLengthError(Exception):
  41. __doc__ = MESSAGE = "Message is too long to send"
  42. def __str__(self) -> str:
  43. s = self.MESSAGE
  44. if self.args:
  45. s = "{}: {}".format(s, " ".join(self.args))
  46. s = "%s." % s
  47. return s
  48. class DNSLookupError(IOError):
  49. __doc__ = MESSAGE = "DNS lookup failed"
  50. def __str__(self) -> str:
  51. s = self.MESSAGE
  52. if self.args:
  53. s = "{}: {}".format(s, " ".join(self.args))
  54. s = "%s." % s
  55. return s
  56. class ConnectInProgressError(Exception):
  57. """A connect operation was started and isn't done yet."""
  58. # connection errors
  59. class ConnectError(Exception):
  60. __doc__ = MESSAGE = "An error occurred while connecting"
  61. def __init__(self, osError=None, string=""):
  62. self.osError = osError
  63. Exception.__init__(self, string)
  64. def __str__(self) -> str:
  65. s = self.MESSAGE
  66. if self.osError:
  67. s = f"{s}: {self.osError}"
  68. if self.args[0]:
  69. s = f"{s}: {self.args[0]}"
  70. s = "%s." % s
  71. return s
  72. class ConnectBindError(ConnectError):
  73. __doc__ = MESSAGE = "Couldn't bind"
  74. class UnknownHostError(ConnectError):
  75. __doc__ = MESSAGE = "Hostname couldn't be looked up"
  76. class NoRouteError(ConnectError):
  77. __doc__ = MESSAGE = "No route to host"
  78. class ConnectionRefusedError(ConnectError):
  79. __doc__ = MESSAGE = "Connection was refused by other side"
  80. class TCPTimedOutError(ConnectError):
  81. __doc__ = MESSAGE = "TCP connection timed out"
  82. class BadFileError(ConnectError):
  83. __doc__ = MESSAGE = "File used for UNIX socket is no good"
  84. class ServiceNameUnknownError(ConnectError):
  85. __doc__ = MESSAGE = "Service name given as port is unknown"
  86. class UserError(ConnectError):
  87. __doc__ = MESSAGE = "User aborted connection"
  88. class TimeoutError(UserError):
  89. __doc__ = MESSAGE = "User timeout caused connection failure"
  90. class SSLError(ConnectError):
  91. __doc__ = MESSAGE = "An SSL error occurred"
  92. class VerifyError(Exception):
  93. __doc__ = MESSAGE = "Could not verify something that was supposed to be signed."
  94. class PeerVerifyError(VerifyError):
  95. __doc__ = MESSAGE = "The peer rejected our verify error."
  96. class CertificateError(Exception):
  97. __doc__ = MESSAGE = "We did not find a certificate where we expected to find one."
  98. try:
  99. import errno
  100. errnoMapping = {
  101. errno.ENETUNREACH: NoRouteError,
  102. errno.ECONNREFUSED: ConnectionRefusedError,
  103. errno.ETIMEDOUT: TCPTimedOutError,
  104. }
  105. if hasattr(errno, "WSAECONNREFUSED"):
  106. errnoMapping[errno.WSAECONNREFUSED] = ConnectionRefusedError # type: ignore[attr-defined]
  107. errnoMapping[errno.WSAENETUNREACH] = NoRouteError # type: ignore[attr-defined]
  108. except ImportError:
  109. errnoMapping = {}
  110. def getConnectError(e):
  111. """Given a socket exception, return connection error."""
  112. if isinstance(e, Exception):
  113. args = e.args
  114. else:
  115. args = e
  116. try:
  117. number, string = args
  118. except ValueError:
  119. return ConnectError(string=e)
  120. if hasattr(socket, "gaierror") and isinstance(e, socket.gaierror):
  121. # Only works in 2.2 in newer. Really that means always; #5978 covers
  122. # this and other weirdnesses in this function.
  123. klass = UnknownHostError
  124. else:
  125. klass = errnoMapping.get(number, ConnectError)
  126. return klass(number, string)
  127. class ConnectionClosed(Exception):
  128. """
  129. Connection was closed, whether cleanly or non-cleanly.
  130. """
  131. class ConnectionLost(ConnectionClosed):
  132. __doc__ = MESSAGE = """
  133. Connection to the other side was lost in a non-clean fashion
  134. """
  135. def __str__(self) -> str:
  136. s = self.MESSAGE.strip().splitlines()[:1]
  137. if self.args:
  138. s.append(": ")
  139. s.append(" ".join(self.args))
  140. s.append(".")
  141. return "".join(s)
  142. class ConnectionAborted(ConnectionLost):
  143. """
  144. Connection was aborted locally, using
  145. L{twisted.internet.interfaces.ITCPTransport.abortConnection}.
  146. @since: 11.1
  147. """
  148. MESSAGE = "Connection was aborted locally using " "ITCPTransport.abortConnection"
  149. class ConnectionDone(ConnectionClosed):
  150. __doc__ = MESSAGE = "Connection was closed cleanly"
  151. def __str__(self) -> str:
  152. s = self.MESSAGE
  153. if self.args:
  154. s = "{}: {}".format(s, " ".join(self.args))
  155. s = "%s." % s
  156. return s
  157. class FileDescriptorOverrun(ConnectionLost):
  158. """
  159. A mis-use of L{IUNIXTransport.sendFileDescriptor} caused the connection to
  160. be closed.
  161. Each file descriptor sent using C{sendFileDescriptor} must be associated
  162. with at least one byte sent using L{ITransport.write}. If at any point
  163. fewer bytes have been written than file descriptors have been sent, the
  164. connection is closed with this exception.
  165. """
  166. MESSAGE = (
  167. "A mis-use of IUNIXTransport.sendFileDescriptor caused "
  168. "the connection to be closed."
  169. )
  170. class ConnectionFdescWentAway(ConnectionLost):
  171. __doc__ = MESSAGE = "Uh" # TODO
  172. class AlreadyCalled(ValueError):
  173. __doc__ = MESSAGE = "Tried to cancel an already-called event"
  174. def __str__(self) -> str:
  175. s = self.MESSAGE
  176. if self.args:
  177. s = "{}: {}".format(s, " ".join(self.args))
  178. s = "%s." % s
  179. return s
  180. class AlreadyCancelled(ValueError):
  181. __doc__ = MESSAGE = "Tried to cancel an already-cancelled event"
  182. def __str__(self) -> str:
  183. s = self.MESSAGE
  184. if self.args:
  185. s = "{}: {}".format(s, " ".join(self.args))
  186. s = "%s." % s
  187. return s
  188. class PotentialZombieWarning(Warning):
  189. """
  190. Emitted when L{IReactorProcess.spawnProcess} is called in a way which may
  191. result in termination of the created child process not being reported.
  192. Deprecated in Twisted 10.0.
  193. """
  194. MESSAGE = (
  195. "spawnProcess called, but the SIGCHLD handler is not "
  196. "installed. This probably means you have not yet "
  197. "called reactor.run, or called "
  198. "reactor.run(installSignalHandler=0). You will probably "
  199. "never see this process finish, and it may become a "
  200. "zombie process."
  201. )
  202. deprecate.deprecatedModuleAttribute(
  203. Version("Twisted", 10, 0, 0),
  204. "There is no longer any potential for zombie process.",
  205. __name__,
  206. "PotentialZombieWarning",
  207. )
  208. class ProcessDone(ConnectionDone):
  209. __doc__ = MESSAGE = "A process has ended without apparent errors"
  210. def __init__(self, status):
  211. Exception.__init__(self, "process finished with exit code 0")
  212. self.exitCode = 0
  213. self.signal = None
  214. self.status = status
  215. class ProcessTerminated(ConnectionLost):
  216. __doc__ = MESSAGE = """
  217. A process has ended with a probable error condition
  218. @ivar exitCode: See L{__init__}
  219. @ivar signal: See L{__init__}
  220. @ivar status: See L{__init__}
  221. """
  222. def __init__(self, exitCode=None, signal=None, status=None):
  223. """
  224. @param exitCode: The exit status of the process. This is roughly like
  225. the value you might pass to L{os._exit}. This is L{None} if the
  226. process exited due to a signal.
  227. @type exitCode: L{int} or L{None}
  228. @param signal: The exit signal of the process. This is L{None} if the
  229. process did not exit due to a signal.
  230. @type signal: L{int} or L{None}
  231. @param status: The exit code of the process. This is a platform
  232. specific combination of the exit code and the exit signal. See
  233. L{os.WIFEXITED} and related functions.
  234. @type status: L{int}
  235. """
  236. self.exitCode = exitCode
  237. self.signal = signal
  238. self.status = status
  239. s = "process ended"
  240. if exitCode is not None:
  241. s = s + " with exit code %s" % exitCode
  242. if signal is not None:
  243. s = s + " by signal %s" % signal
  244. Exception.__init__(self, s)
  245. class ProcessExitedAlready(Exception):
  246. """
  247. The process has already exited and the operation requested can no longer
  248. be performed.
  249. """
  250. class NotConnectingError(RuntimeError):
  251. __doc__ = (
  252. MESSAGE
  253. ) = "The Connector was not connecting when it was asked to stop connecting"
  254. def __str__(self) -> str:
  255. s = self.MESSAGE
  256. if self.args:
  257. s = "{}: {}".format(s, " ".join(self.args))
  258. s = "%s." % s
  259. return s
  260. class NotListeningError(RuntimeError):
  261. __doc__ = MESSAGE = "The Port was not listening when it was asked to stop listening"
  262. def __str__(self) -> str:
  263. s = self.MESSAGE
  264. if self.args:
  265. s = "{}: {}".format(s, " ".join(self.args))
  266. s = "%s." % s
  267. return s
  268. class ReactorNotRunning(RuntimeError):
  269. """
  270. Error raised when trying to stop a reactor which is not running.
  271. """
  272. class ReactorNotRestartable(RuntimeError):
  273. """
  274. Error raised when trying to run a reactor which was stopped.
  275. """
  276. class ReactorAlreadyRunning(RuntimeError):
  277. """
  278. Error raised when trying to start the reactor multiple times.
  279. """
  280. class ReactorAlreadyInstalledError(AssertionError):
  281. """
  282. Could not install reactor because one is already installed.
  283. """
  284. class ConnectingCancelledError(Exception):
  285. """
  286. An C{Exception} that will be raised when an L{IStreamClientEndpoint} is
  287. cancelled before it connects.
  288. @ivar address: The L{IAddress} that is the destination of the
  289. cancelled L{IStreamClientEndpoint}.
  290. """
  291. def __init__(self, address):
  292. """
  293. @param address: The L{IAddress} that is the destination of the
  294. L{IStreamClientEndpoint} that was cancelled.
  295. """
  296. Exception.__init__(self, address)
  297. self.address = address
  298. class NoProtocol(Exception):
  299. """
  300. An C{Exception} that will be raised when the factory given to a
  301. L{IStreamClientEndpoint} returns L{None} from C{buildProtocol}.
  302. """
  303. class UnsupportedAddressFamily(Exception):
  304. """
  305. An attempt was made to use a socket with an address family (eg I{AF_INET},
  306. I{AF_INET6}, etc) which is not supported by the reactor.
  307. """
  308. class UnsupportedSocketType(Exception):
  309. """
  310. An attempt was made to use a socket of a type (eg I{SOCK_STREAM},
  311. I{SOCK_DGRAM}, etc) which is not supported by the reactor.
  312. """
  313. class AlreadyListened(Exception):
  314. """
  315. An attempt was made to listen on a file descriptor which can only be
  316. listened on once.
  317. """
  318. class InvalidAddressError(ValueError):
  319. """
  320. An invalid address was specified (i.e. neither IPv4 or IPv6, or expected
  321. one and got the other).
  322. @ivar address: See L{__init__}
  323. @ivar message: See L{__init__}
  324. """
  325. def __init__(self, address, message):
  326. """
  327. @param address: The address that was provided.
  328. @type address: L{bytes}
  329. @param message: A native string of additional information provided by
  330. the calling context.
  331. @type address: L{str}
  332. """
  333. self.address = address
  334. self.message = message
  335. __all__ = [
  336. "BindError",
  337. "CannotListenError",
  338. "MulticastJoinError",
  339. "MessageLengthError",
  340. "DNSLookupError",
  341. "ConnectInProgressError",
  342. "ConnectError",
  343. "ConnectBindError",
  344. "UnknownHostError",
  345. "NoRouteError",
  346. "ConnectionRefusedError",
  347. "TCPTimedOutError",
  348. "BadFileError",
  349. "ServiceNameUnknownError",
  350. "UserError",
  351. "TimeoutError",
  352. "SSLError",
  353. "VerifyError",
  354. "PeerVerifyError",
  355. "CertificateError",
  356. "getConnectError",
  357. "ConnectionClosed",
  358. "ConnectionLost",
  359. "ConnectionDone",
  360. "ConnectionFdescWentAway",
  361. "AlreadyCalled",
  362. "AlreadyCancelled",
  363. "PotentialZombieWarning",
  364. "ProcessDone",
  365. "ProcessTerminated",
  366. "ProcessExitedAlready",
  367. "NotConnectingError",
  368. "NotListeningError",
  369. "ReactorNotRunning",
  370. "ReactorAlreadyRunning",
  371. "ReactorAlreadyInstalledError",
  372. "ConnectingCancelledError",
  373. "UnsupportedAddressFamily",
  374. "UnsupportedSocketType",
  375. "InvalidAddressError",
  376. ]