normalize.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. """normalize."""
  2. from __future__ import annotations
  3. import ast
  4. import sys
  5. from functools import wraps
  6. from typing import Callable, TypeVar
  7. from wandb_gql.client import RetryError
  8. from wandb import env
  9. from wandb.errors import CommError, Error
  10. from wandb.util import parse_backend_error_messages
  11. _F = TypeVar("_F", bound=Callable)
  12. def normalize_exceptions(func: _F) -> _F:
  13. """Function decorator for catching common errors and re-raising as wandb.Error."""
  14. @wraps(func)
  15. def wrapper(*args, **kwargs):
  16. import requests
  17. message = "Whoa, you found a bug."
  18. try:
  19. return func(*args, **kwargs)
  20. except requests.HTTPError as error:
  21. errors = parse_backend_error_messages(error.response)
  22. status = error.response.status_code
  23. if errors:
  24. message = f"HTTP {status}: {'; '.join(errors)}"
  25. elif error.response.text:
  26. message = f"HTTP {status}: {error.response.text}"
  27. elif error.response.reason:
  28. # Visually different to distinguish backend errors from
  29. # standard HTTP status descriptions.
  30. message = f"HTTP {status} ({error.response.reason})"
  31. else:
  32. message = f"HTTP {status}"
  33. raise CommError(message, error)
  34. except RetryError as err:
  35. if (
  36. "response" in dir(err.last_exception)
  37. and err.last_exception.response is not None
  38. ):
  39. try:
  40. message = err.last_exception.response.json().get(
  41. "errors", [{"message": message}]
  42. )[0]["message"]
  43. except ValueError:
  44. message = err.last_exception.response.text
  45. else:
  46. message = err.last_exception
  47. if env.is_debug():
  48. raise err.last_exception.with_traceback(sys.exc_info()[2])
  49. else:
  50. raise CommError(message, err.last_exception).with_traceback(
  51. sys.exc_info()[2]
  52. )
  53. except Error:
  54. raise
  55. except Exception as err:
  56. # gql raises server errors with dict's as strings...
  57. if len(err.args) > 0:
  58. payload = err.args[0]
  59. else:
  60. payload = err
  61. if str(payload).startswith("{"):
  62. message = ast.literal_eval(str(payload))["message"]
  63. else:
  64. message = str(err)
  65. if env.is_debug():
  66. raise
  67. else:
  68. raise CommError(message, err).with_traceback(sys.exc_info()[2])
  69. return wrapper