exceptions.py 2.0 KB

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