exception_handler.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. # coding=utf-8
  2. """
  3. 插件异常处理器
  4. 对插件运行时异常进行分类和标准化处理
  5. """
  6. from plugin.services.error_codes import PluginErrorCode
  7. from common.utils.logger import maxkb_logger
  8. class PluginException(Exception):
  9. """插件基础异常"""
  10. def __init__(self, error_code: str, message: str, detail: dict = None):
  11. self.error_code = error_code
  12. self.message = message
  13. self.detail = detail or {}
  14. super().__init__(message)
  15. class PluginNotFoundException(PluginException):
  16. """插件不存在异常"""
  17. def __init__(self, plugin_id: str = ''):
  18. code, msg = PluginErrorCode.PLUGIN_NOT_FOUND
  19. super().__init__(code, msg, {'plugin_id': plugin_id})
  20. class PluginAlreadyExistsException(PluginException):
  21. """插件已存在异常"""
  22. def __init__(self, code: str = ''):
  23. error_code, msg = PluginErrorCode.PLUGIN_ALREADY_EXISTS
  24. super().__init__(error_code, msg, {'plugin_code': code})
  25. class PluginNotInstalledException(PluginException):
  26. """插件未安装异常"""
  27. def __init__(self, plugin_id: str = ''):
  28. error_code, msg = PluginErrorCode.PLUGIN_NOT_INSTALLED
  29. super().__init__(error_code, msg, {'plugin_id': plugin_id})
  30. class PluginStatusException(PluginException):
  31. """插件状态异常"""
  32. def __init__(self, plugin_id: str = '', current_status: str = ''):
  33. error_code, msg = PluginErrorCode.PLUGIN_STATUS_ERROR
  34. super().__init__(error_code, msg, {
  35. 'plugin_id': plugin_id,
  36. 'current_status': current_status
  37. })
  38. class PluginTestException(PluginException):
  39. """插件测试异常"""
  40. def __init__(self, error_code: str = None, message: str = '', detail: dict = None):
  41. if not error_code:
  42. error_code, default_msg = PluginErrorCode.TEST_FAILED
  43. message = message or default_msg
  44. super().__init__(error_code, message, detail or {})
  45. class PluginTestTimeoutException(PluginTestException):
  46. """插件测试超时异常"""
  47. def __init__(self, timeout_ms: int = 0):
  48. error_code, msg = PluginErrorCode.TEST_TIMEOUT
  49. super().__init__(error_code, msg, {'timeout_ms': timeout_ms})
  50. class PluginSchemaException(PluginException):
  51. """插件 Schema 异常"""
  52. def __init__(self, error_code: str = None, message: str = '', detail: dict = None):
  53. if not error_code:
  54. error_code, default_msg = PluginErrorCode.SCHEMA_INVALID
  55. message = message or default_msg
  56. super().__init__(error_code, message, detail or {})
  57. class PluginExceptionHandler:
  58. """插件异常处理器"""
  59. @staticmethod
  60. def handle(exception: Exception) -> dict:
  61. """
  62. 处理插件异常,返回标准化错误响应
  63. """
  64. if isinstance(exception, PluginException):
  65. return {
  66. 'success': False,
  67. 'error_code': exception.error_code,
  68. 'message': exception.message,
  69. 'detail': exception.detail
  70. }
  71. # 未知异常
  72. maxkb_logger.error(f"Unhandled plugin exception: {exception}", exc_info=True)
  73. return {
  74. 'success': False,
  75. 'error_code': 'PLUGIN_999',
  76. 'message': '插件内部错误',
  77. 'detail': {'original_error': str(exception)}
  78. }
  79. @staticmethod
  80. def to_api_response(exception: Exception) -> dict:
  81. """转换为 API 响应格式"""
  82. error = PluginExceptionHandler.handle(exception)
  83. return {
  84. 'code': 400,
  85. 'message': error['message'],
  86. 'data': {
  87. 'error_code': error['error_code'],
  88. 'detail': error['detail']
  89. }
  90. }