exceptions.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. # -*- coding: utf-8 -*-
  2. # (c) Nelen & Schuurmans
  3. from typing import Any
  4. from typing import Optional
  5. from typing import Union
  6. from pydantic import create_model
  7. from pydantic import ValidationError
  8. from pydantic.error_wrappers import ErrorWrapper
  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(ValidationError):
  43. def __init__(self, err_or_msg: Union[ValidationError, str]):
  44. if isinstance(err_or_msg, ValidationError):
  45. errors = err_or_msg.raw_errors
  46. else:
  47. errors = [ErrorWrapper(ValueError(err_or_msg), "*")]
  48. super().__init__(errors, request_model)
  49. def __str__(self) -> str:
  50. errors = self.errors()
  51. if len(errors) == 1:
  52. error = errors[0]
  53. loc = "'" + ",".join([str(x) for x in error["loc"]]) + "' "
  54. if loc == "'*' ":
  55. loc = ""
  56. return f"validation error: {loc}{error['msg']}"
  57. return super().__str__()
  58. class Unauthorized(Exception):
  59. pass
  60. class PermissionDenied(Exception):
  61. pass