exceptions.py 2.0 KB

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