Преглед на файлове

fix: handle detailed error type

Yeuoly преди 5 месеца
родител
ревизия
5c6d919a4a

+ 0 - 1
api/core/plugin/entities/plugin_daemon.py

@@ -108,7 +108,6 @@ class PluginDaemonError(BaseModel):
 
     error_type: str
     message: str
-    args: Optional[dict] = None
 
 
 class PluginDaemonInnerError(Exception):

+ 26 - 17
api/core/plugin/manager/base.py

@@ -2,7 +2,7 @@ import inspect
 import json
 import logging
 from collections.abc import Callable, Generator
-from typing import Optional, TypeVar
+from typing import TypeVar
 
 import requests
 from pydantic import BaseModel
@@ -16,12 +16,14 @@ from core.model_runtime.errors.invoke import (
     InvokeRateLimitError,
     InvokeServerUnavailableError,
 )
+from core.model_runtime.errors.validate import CredentialsValidateFailedError
 from core.plugin.entities.plugin_daemon import PluginDaemonBasicResponse, PluginDaemonError, PluginDaemonInnerError
 from core.plugin.manager.exc import (
     PluginDaemonBadRequestError,
     PluginDaemonInternalServerError,
     PluginDaemonNotFoundError,
     PluginDaemonUnauthorizedError,
+    PluginInvokeError,
     PluginPermissionDeniedError,
     PluginUniqueIdentifierError,
 )
@@ -144,7 +146,7 @@ class BasePluginManager:
             except Exception as e:
                 raise ValueError(f"{rep.message}, code: {rep.code}")
 
-            self._handle_plugin_daemon_error(error.error_type, error.message, error.args)
+            self._handle_plugin_daemon_error(error.error_type, error.message)
         if rep.data is None:
             frame = inspect.currentframe()
             raise ValueError(f"got empty data from plugin daemon: {frame.f_lineno if frame else 'unknown'}")
@@ -183,32 +185,39 @@ class BasePluginManager:
                     except Exception as e:
                         raise PluginDaemonInnerError(code=rep.code, message=rep.message)
 
-                    self._handle_plugin_daemon_error(error.error_type, error.message, error.args)
+                    self._handle_plugin_daemon_error(error.error_type, error.message)
                 raise ValueError(f"plugin daemon: {rep.message}, code: {rep.code}")
             if rep.data is None:
                 frame = inspect.currentframe()
                 raise ValueError(f"got empty data from plugin daemon: {frame.f_lineno if frame else 'unknown'}")
             yield rep.data
 
-    def _handle_plugin_daemon_error(self, error_type: str, message: str, args: Optional[dict] = None):
+    def _handle_plugin_daemon_error(self, error_type: str, message: str):
         """
         handle the error from plugin daemon
         """
-        args = args or {}
-
         match error_type:
             case PluginDaemonInnerError.__name__:
                 raise PluginDaemonInnerError(code=-500, message=message)
-            case InvokeRateLimitError.__name__:
-                raise InvokeRateLimitError(description=args.get("description"))
-            case InvokeAuthorizationError.__name__:
-                raise InvokeAuthorizationError(description=args.get("description"))
-            case InvokeBadRequestError.__name__:
-                raise InvokeBadRequestError(description=args.get("description"))
-            case InvokeConnectionError.__name__:
-                raise InvokeConnectionError(description=args.get("description"))
-            case InvokeServerUnavailableError.__name__:
-                raise InvokeServerUnavailableError(description=args.get("description"))
+            case PluginInvokeError.__name__:
+                error_object = json.loads(message)
+                invoke_error_type = error_object.get("error_type")
+                args = error_object.get("args")
+                match invoke_error_type:
+                    case InvokeRateLimitError.__name__:
+                        raise InvokeRateLimitError(description=args.get("description"))
+                    case InvokeAuthorizationError.__name__:
+                        raise InvokeAuthorizationError(description=args.get("description"))
+                    case InvokeBadRequestError.__name__:
+                        raise InvokeBadRequestError(description=args.get("description"))
+                    case InvokeConnectionError.__name__:
+                        raise InvokeConnectionError(description=args.get("description"))
+                    case InvokeServerUnavailableError.__name__:
+                        raise InvokeServerUnavailableError(description=args.get("description"))
+                    case CredentialsValidateFailedError.__name__:
+                        raise CredentialsValidateFailedError(error_object.get("message"))
+                    case _:
+                        raise PluginInvokeError(description=message)
             case PluginDaemonInternalServerError.__name__:
                 raise PluginDaemonInternalServerError(description=message)
             case PluginDaemonBadRequestError.__name__:
@@ -222,4 +231,4 @@ class BasePluginManager:
             case PluginPermissionDeniedError.__name__:
                 raise PluginPermissionDeniedError(description=message)
             case _:
-                raise Exception(f"got unknown error from plugin daemon: {error_type}, message: {message}, args: {args}")
+                raise Exception(f"got unknown error from plugin daemon: {error_type}, message: {message}")

+ 4 - 0
api/core/plugin/manager/exc.py

@@ -21,6 +21,10 @@ class PluginDaemonNotFoundError(PluginDaemonError):
     description: str = "Not Found"
 
 
+class PluginInvokeError(PluginDaemonError):
+    description: str = "Invoke Error"
+
+
 class PluginUniqueIdentifierError(PluginDaemonError):
     description: str = "Unique Identifier Error"
 

+ 7 - 1
api/services/tools/builtin_tools_manage_service.py

@@ -6,6 +6,7 @@ from configs import dify_config
 from core.helper.position_helper import is_filtered
 from core.model_runtime.utils.encoders import jsonable_encoder
 from core.plugin.entities.plugin import GenericProviderID
+from core.plugin.manager.exc import PluginInvokeError
 from core.tools.builtin_tool.providers._positions import BuiltinToolProviderSort
 from core.tools.entities.api_entities import ToolApiEntity, ToolProviderApiEntity
 from core.tools.errors import ToolNotFoundError, ToolProviderCredentialValidationError, ToolProviderNotFoundError
@@ -137,7 +138,12 @@ class BuiltinToolManageService:
             provider_controller.validate_credentials(user_id, credentials)
             # encrypt credentials
             credentials = tool_configuration.encrypt(credentials)
-        except (ToolProviderNotFoundError, ToolNotFoundError, ToolProviderCredentialValidationError) as e:
+        except (
+            PluginInvokeError,
+            ToolProviderNotFoundError,
+            ToolNotFoundError,
+            ToolProviderCredentialValidationError,
+        ) as e:
             raise ValueError(str(e))
 
         if provider is None: