error.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. # Sync content of this file with devtools/ya/core/error/__init__.py
  2. TEMPORARY_ERROR_MESSAGES = [
  3. 'Connection reset by peer',
  4. 'Connection timed out',
  5. 'Function not implemented',
  6. 'I/O operation on closed file',
  7. 'Internal Server Error',
  8. 'Network connection closed unexpectedly',
  9. 'Network is unreachable',
  10. 'No route to host',
  11. 'No space left on device',
  12. 'Not enough space',
  13. 'Temporary failure in name resolution',
  14. 'The read operation timed out',
  15. 'timeout: timed out',
  16. 'no response given after', # sandbox.common.rest.Client.TimeoutExceeded
  17. ]
  18. # Node exit codes
  19. class ExitCodes(object):
  20. GENERIC_ERROR = 1
  21. # 2 is reserved not to be confused with bash's exit code
  22. # For more info see https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
  23. _ = 2
  24. UNHANDLED_EXCEPTION = 3
  25. CONFIGURE_ERROR = 8
  26. NO_TESTS_COLLECTED = 9
  27. TEST_FAILED = 10
  28. INFRASTRUCTURE_ERROR = 12
  29. NOT_RETRIABLE_ERROR = 13
  30. YT_STORE_FETCH_ERROR = 14
  31. def merge_exit_codes(exit_codes):
  32. return max(e if e >= 0 else 1 for e in exit_codes) if exit_codes else 0
  33. def is_temporary_error(exc):
  34. import logging
  35. logger = logging.getLogger(__name__)
  36. if getattr(exc, 'temporary', False):
  37. logger.debug("Exception has temporary attribute: %s", exc)
  38. return True
  39. import errno
  40. err = getattr(exc, 'errno', None)
  41. if err == errno.ECONNREFUSED or err == errno.ENETUNREACH:
  42. logger.debug("Exception has errno attribute: %s (errno=%s)", exc, err)
  43. return True
  44. import socket
  45. if isinstance(exc, socket.timeout) or isinstance(getattr(exc, 'reason', None), socket.timeout):
  46. logger.debug("Socket timeout exception: %s", exc)
  47. return True
  48. if isinstance(exc, socket.gaierror):
  49. logger.debug("Getaddrinfo exception: %s", exc)
  50. return True
  51. try:
  52. import urllib2
  53. import httplib
  54. except ImportError:
  55. import urllib.request as urllib2
  56. import http.client as httplib
  57. if isinstance(exc, urllib2.HTTPError) and exc.code in (429,):
  58. logger.debug("urllib2.HTTPError: %s", exc)
  59. return True
  60. if isinstance(exc, httplib.IncompleteRead):
  61. logger.debug("IncompleteRead exception: %s", exc)
  62. return True
  63. exc_str = str(exc)
  64. for message in TEMPORARY_ERROR_MESSAGES:
  65. if message in exc_str:
  66. logger.debug("Found temporary error pattern (%s): %s", message, exc_str)
  67. return True
  68. return False