exceptions.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. """
  2. Global Django exception and warning classes.
  3. """
  4. class FieldDoesNotExist(Exception):
  5. """The requested model field does not exist"""
  6. pass
  7. class AppRegistryNotReady(Exception):
  8. """The django.apps registry is not populated yet"""
  9. pass
  10. class ObjectDoesNotExist(Exception):
  11. """The requested object does not exist"""
  12. silent_variable_failure = True
  13. class MultipleObjectsReturned(Exception):
  14. """The query returned multiple objects when only one was expected."""
  15. pass
  16. class SuspiciousOperation(Exception):
  17. """The user did something suspicious"""
  18. class SuspiciousMultipartForm(SuspiciousOperation):
  19. """Suspect MIME request in multipart form data"""
  20. pass
  21. class SuspiciousFileOperation(SuspiciousOperation):
  22. """A Suspicious filesystem operation was attempted"""
  23. pass
  24. class DisallowedHost(SuspiciousOperation):
  25. """HTTP_HOST header contains invalid value"""
  26. pass
  27. class DisallowedRedirect(SuspiciousOperation):
  28. """Redirect to scheme not in allowed list"""
  29. pass
  30. class TooManyFieldsSent(SuspiciousOperation):
  31. """
  32. The number of fields in a GET or POST request exceeded
  33. settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.
  34. """
  35. pass
  36. class RequestDataTooBig(SuspiciousOperation):
  37. """
  38. The size of the request (excluding any file uploads) exceeded
  39. settings.DATA_UPLOAD_MAX_MEMORY_SIZE.
  40. """
  41. pass
  42. class RequestAborted(Exception):
  43. """The request was closed before it was completed, or timed out."""
  44. pass
  45. class PermissionDenied(Exception):
  46. """The user did not have permission to do that"""
  47. pass
  48. class ViewDoesNotExist(Exception):
  49. """The requested view does not exist"""
  50. pass
  51. class MiddlewareNotUsed(Exception):
  52. """This middleware is not used in this server configuration"""
  53. pass
  54. class ImproperlyConfigured(Exception):
  55. """Django is somehow improperly configured"""
  56. pass
  57. class FieldError(Exception):
  58. """Some kind of problem with a model field."""
  59. pass
  60. NON_FIELD_ERRORS = '__all__'
  61. class ValidationError(Exception):
  62. """An error while validating data."""
  63. def __init__(self, message, code=None, params=None):
  64. """
  65. The `message` argument can be a single error, a list of errors, or a
  66. dictionary that maps field names to lists of errors. What we define as
  67. an "error" can be either a simple string or an instance of
  68. ValidationError with its message attribute set, and what we define as
  69. list or dictionary can be an actual `list` or `dict` or an instance
  70. of ValidationError with its `error_list` or `error_dict` attribute set.
  71. """
  72. super().__init__(message, code, params)
  73. if isinstance(message, ValidationError):
  74. if hasattr(message, 'error_dict'):
  75. message = message.error_dict
  76. elif not hasattr(message, 'message'):
  77. message = message.error_list
  78. else:
  79. message, code, params = message.message, message.code, message.params
  80. if isinstance(message, dict):
  81. self.error_dict = {}
  82. for field, messages in message.items():
  83. if not isinstance(messages, ValidationError):
  84. messages = ValidationError(messages)
  85. self.error_dict[field] = messages.error_list
  86. elif isinstance(message, list):
  87. self.error_list = []
  88. for message in message:
  89. # Normalize plain strings to instances of ValidationError.
  90. if not isinstance(message, ValidationError):
  91. message = ValidationError(message)
  92. if hasattr(message, 'error_dict'):
  93. self.error_list.extend(sum(message.error_dict.values(), []))
  94. else:
  95. self.error_list.extend(message.error_list)
  96. else:
  97. self.message = message
  98. self.code = code
  99. self.params = params
  100. self.error_list = [self]
  101. @property
  102. def message_dict(self):
  103. # Trigger an AttributeError if this ValidationError
  104. # doesn't have an error_dict.
  105. getattr(self, 'error_dict')
  106. return dict(self)
  107. @property
  108. def messages(self):
  109. if hasattr(self, 'error_dict'):
  110. return sum(dict(self).values(), [])
  111. return list(self)
  112. def update_error_dict(self, error_dict):
  113. if hasattr(self, 'error_dict'):
  114. for field, error_list in self.error_dict.items():
  115. error_dict.setdefault(field, []).extend(error_list)
  116. else:
  117. error_dict.setdefault(NON_FIELD_ERRORS, []).extend(self.error_list)
  118. return error_dict
  119. def __iter__(self):
  120. if hasattr(self, 'error_dict'):
  121. for field, errors in self.error_dict.items():
  122. yield field, list(ValidationError(errors))
  123. else:
  124. for error in self.error_list:
  125. message = error.message
  126. if error.params:
  127. message %= error.params
  128. yield str(message)
  129. def __str__(self):
  130. if hasattr(self, 'error_dict'):
  131. return repr(dict(self))
  132. return repr(list(self))
  133. def __repr__(self):
  134. return 'ValidationError(%s)' % self
  135. class EmptyResultSet(Exception):
  136. """A database query predicate is impossible."""
  137. pass
  138. class SynchronousOnlyOperation(Exception):
  139. """The user tried to call a sync-only function from an async context."""
  140. pass