exceptions.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. """Exceptions used in the auth system."""
  2. from __future__ import annotations
  3. import http
  4. from collections.abc import Mapping
  5. class HTTPException(Exception):
  6. """HTTP exception that you can raise to return a specific HTTP error response.
  7. Since this is defined in the auth module, we default to a 401 status code.
  8. Args:
  9. status_code: HTTP status code for the error. Defaults to 401 "Unauthorized".
  10. detail: Detailed error message. If `None`, uses a default
  11. message based on the status code.
  12. headers: Additional HTTP headers to include in the error response.
  13. Example:
  14. Default:
  15. ```python
  16. raise HTTPException()
  17. # HTTPException(status_code=401, detail='Unauthorized')
  18. ```
  19. Add headers:
  20. ```python
  21. raise HTTPException(headers={"X-Custom-Header": "Custom Value"})
  22. # HTTPException(status_code=401, detail='Unauthorized', headers={"WWW-Authenticate": "Bearer"})
  23. ```
  24. Custom error:
  25. ```python
  26. raise HTTPException(status_code=404, detail="Not found")
  27. ```
  28. """
  29. def __init__(
  30. self,
  31. status_code: int = 401,
  32. detail: str | None = None,
  33. headers: Mapping[str, str] | None = None,
  34. ) -> None:
  35. if detail is None:
  36. detail = http.HTTPStatus(status_code).phrase
  37. self.status_code = status_code
  38. self.detail = detail
  39. self.headers = headers
  40. def __str__(self) -> str:
  41. return f"{self.status_code}: {self.detail}"
  42. def __repr__(self) -> str:
  43. class_name = self.__class__.__name__
  44. return f"{class_name}(status_code={self.status_code!r}, detail={self.detail!r})"
  45. __all__ = ["HTTPException"]