exceptions.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # (c) Nelen & Schuurmans
  2. from typing import Any
  3. from typing import Dict
  4. from typing import List
  5. from typing import Optional
  6. from typing import Union
  7. from pydantic import create_model
  8. from pydantic import ValidationError
  9. __all__ = [
  10. "AlreadyExists",
  11. "Conflict",
  12. "DoesNotExist",
  13. "PermissionDenied",
  14. "PreconditionFailed",
  15. "BadRequest",
  16. "Unauthorized",
  17. "BadRequest",
  18. ]
  19. class DoesNotExist(Exception):
  20. def __init__(self, name: str, id: Optional[int] = None):
  21. super().__init__()
  22. self.name = name
  23. self.id = id
  24. def __str__(self):
  25. if self.id:
  26. return f"does not exist: {self.name} with id={self.id}"
  27. else:
  28. return f"does not exist: {self.name}"
  29. class Conflict(Exception):
  30. def __init__(self, msg: Optional[str] = None):
  31. super().__init__(msg)
  32. class AlreadyExists(Conflict):
  33. def __init__(self, id: Optional[int] = None):
  34. super().__init__(f"record with id={id} already exists")
  35. class PreconditionFailed(Exception):
  36. def __init__(self, msg: str = "precondition failed", obj: Any = None):
  37. super().__init__(msg)
  38. self.obj = obj
  39. # pydantic.ValidationError needs some model; for us it doesn't matter
  40. # We do it the same way as FastAPI does it.
  41. request_model = create_model("Request")
  42. class BadRequest(Exception):
  43. def __init__(self, err_or_msg: Union[ValidationError, str]):
  44. self._internal_error = err_or_msg
  45. super().__init__(err_or_msg)
  46. def errors(self) -> List[Dict]:
  47. if isinstance(self._internal_error, ValidationError):
  48. return self._internal_error.errors()
  49. return [{"error": self}]
  50. def __str__(self) -> str:
  51. error = self._internal_error
  52. if isinstance(error, ValidationError):
  53. error = error.errors()[0]
  54. loc = "'" + ",".join([str(x) for x in error["loc"]]) + "' "
  55. if loc == "'*' ":
  56. loc = ""
  57. return f"validation error: {loc}{error['msg']}"
  58. return f"validation error: {super().__str__()}"
  59. class Unauthorized(Exception):
  60. pass
  61. class PermissionDenied(Exception):
  62. pass