error.py 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. # -*- coding: utf-8 -*-
  2. import traceback
  3. import marshmallow
  4. from hapic.processor import ProcessValidationError
  5. class ErrorBuilderInterface(marshmallow.Schema):
  6. """
  7. ErrorBuilder is a class who represent a Schema (marshmallow.Schema) and
  8. can generate a response content from exception (build_from_exception)
  9. """
  10. def build_from_exception(
  11. self,
  12. exception: Exception,
  13. include_traceback: bool = False,
  14. ) -> dict:
  15. """
  16. Build the error response content from given exception
  17. :param exception: Original exception who invoke this method
  18. :return: a dict representing the error response content
  19. """
  20. raise NotImplementedError()
  21. def build_from_validation_error(
  22. self,
  23. error: ProcessValidationError,
  24. ) -> dict:
  25. """
  26. Build the error response content from given process validation error
  27. :param error: Original ProcessValidationError who invoke this method
  28. :return: a dict representing the error response content
  29. """
  30. raise NotImplementedError()
  31. class DefaultErrorBuilder(ErrorBuilderInterface):
  32. message = marshmallow.fields.String(required=True)
  33. details = marshmallow.fields.Dict(required=False, missing={})
  34. code = marshmallow.fields.Raw(missing=None)
  35. def build_from_exception(
  36. self,
  37. exception: Exception,
  38. include_traceback: bool = False,
  39. ) -> dict:
  40. """
  41. See hapic.error.ErrorBuilderInterface#build_from_exception docstring
  42. """
  43. # TODO: "error_detail" attribute name should be configurable
  44. message = str(exception)
  45. if not message:
  46. message = type(exception).__name__
  47. details = {
  48. 'error_detail': getattr(exception, 'error_detail', {}),
  49. }
  50. if include_traceback:
  51. details['traceback'] = traceback.format_exc()
  52. return {
  53. 'message': message,
  54. 'details': details,
  55. 'code': None,
  56. }
  57. def build_from_validation_error(
  58. self,
  59. error: ProcessValidationError,
  60. ) -> dict:
  61. """
  62. See hapic.error.ErrorBuilderInterface#build_from_validation_error
  63. docstring
  64. """
  65. return {
  66. 'message': error.message,
  67. 'details': error.details,
  68. 'code': None,
  69. }