mirror of
https://github.com/langgenius/dify.git
synced 2025-09-25 09:00:57 +00:00
chore: enhance error message when handling PluginInvokeError (#22908)
This commit is contained in:
parent
45cebf09b0
commit
206bc4b36d
@ -1,3 +1,8 @@
|
|||||||
|
from collections.abc import Mapping
|
||||||
|
|
||||||
|
from pydantic import TypeAdapter
|
||||||
|
|
||||||
|
|
||||||
class PluginDaemonError(Exception):
|
class PluginDaemonError(Exception):
|
||||||
"""Base class for all plugin daemon errors."""
|
"""Base class for all plugin daemon errors."""
|
||||||
|
|
||||||
@ -36,6 +41,21 @@ class PluginDaemonBadRequestError(PluginDaemonClientSideError):
|
|||||||
class PluginInvokeError(PluginDaemonClientSideError):
|
class PluginInvokeError(PluginDaemonClientSideError):
|
||||||
description: str = "Invoke Error"
|
description: str = "Invoke Error"
|
||||||
|
|
||||||
|
def _get_error_object(self) -> Mapping:
|
||||||
|
try:
|
||||||
|
return TypeAdapter(Mapping).validate_json(self.description)
|
||||||
|
except Exception:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def get_error_type(self) -> str:
|
||||||
|
return self._get_error_object().get("error_type", "unknown")
|
||||||
|
|
||||||
|
def get_error_message(self) -> str:
|
||||||
|
try:
|
||||||
|
return self._get_error_object().get("message", "unknown")
|
||||||
|
except Exception:
|
||||||
|
return self.description
|
||||||
|
|
||||||
|
|
||||||
class PluginUniqueIdentifierError(PluginDaemonClientSideError):
|
class PluginUniqueIdentifierError(PluginDaemonClientSideError):
|
||||||
description: str = "Unique Identifier Error"
|
description: str = "Unique Identifier Error"
|
||||||
|
@ -6,7 +6,7 @@ from sqlalchemy.orm import Session
|
|||||||
|
|
||||||
from core.callback_handler.workflow_tool_callback_handler import DifyWorkflowCallbackHandler
|
from core.callback_handler.workflow_tool_callback_handler import DifyWorkflowCallbackHandler
|
||||||
from core.file import File, FileTransferMethod
|
from core.file import File, FileTransferMethod
|
||||||
from core.plugin.impl.exc import PluginDaemonClientSideError
|
from core.plugin.impl.exc import PluginDaemonClientSideError, PluginInvokeError
|
||||||
from core.plugin.impl.plugin import PluginInstaller
|
from core.plugin.impl.plugin import PluginInstaller
|
||||||
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParameter
|
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParameter
|
||||||
from core.tools.errors import ToolInvokeError
|
from core.tools.errors import ToolInvokeError
|
||||||
@ -141,13 +141,36 @@ class ToolNode(BaseNode):
|
|||||||
tenant_id=self.tenant_id,
|
tenant_id=self.tenant_id,
|
||||||
node_id=self.node_id,
|
node_id=self.node_id,
|
||||||
)
|
)
|
||||||
except (PluginDaemonClientSideError, ToolInvokeError) as e:
|
except ToolInvokeError as e:
|
||||||
yield RunCompletedEvent(
|
yield RunCompletedEvent(
|
||||||
run_result=NodeRunResult(
|
run_result=NodeRunResult(
|
||||||
status=WorkflowNodeExecutionStatus.FAILED,
|
status=WorkflowNodeExecutionStatus.FAILED,
|
||||||
inputs=parameters_for_log,
|
inputs=parameters_for_log,
|
||||||
metadata={WorkflowNodeExecutionMetadataKey.TOOL_INFO: tool_info},
|
metadata={WorkflowNodeExecutionMetadataKey.TOOL_INFO: tool_info},
|
||||||
error=f"Failed to transform tool message: {str(e)}",
|
error=f"Failed to invoke tool {node_data.provider_name}: {str(e)}",
|
||||||
|
error_type=type(e).__name__,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except PluginInvokeError as e:
|
||||||
|
yield RunCompletedEvent(
|
||||||
|
run_result=NodeRunResult(
|
||||||
|
status=WorkflowNodeExecutionStatus.FAILED,
|
||||||
|
inputs=parameters_for_log,
|
||||||
|
metadata={WorkflowNodeExecutionMetadataKey.TOOL_INFO: tool_info},
|
||||||
|
error="An error occurred in the plugin, "
|
||||||
|
f"please contact the author of {node_data.provider_name} for help, "
|
||||||
|
f"error type: {e.get_error_type()}, "
|
||||||
|
f"error details: {e.get_error_message()}",
|
||||||
|
error_type=type(e).__name__,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except PluginDaemonClientSideError as e:
|
||||||
|
yield RunCompletedEvent(
|
||||||
|
run_result=NodeRunResult(
|
||||||
|
status=WorkflowNodeExecutionStatus.FAILED,
|
||||||
|
inputs=parameters_for_log,
|
||||||
|
metadata={WorkflowNodeExecutionMetadataKey.TOOL_INFO: tool_info},
|
||||||
|
error=f"Failed to invoke tool, error: {e.description}",
|
||||||
error_type=type(e).__name__,
|
error_type=type(e).__name__,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -111,5 +111,5 @@ def test_tool_node_on_tool_invoke_error(monkeypatch: pytest.MonkeyPatch):
|
|||||||
assert isinstance(result, NodeRunResult)
|
assert isinstance(result, NodeRunResult)
|
||||||
assert result.status == WorkflowNodeExecutionStatus.FAILED
|
assert result.status == WorkflowNodeExecutionStatus.FAILED
|
||||||
assert "oops" in result.error
|
assert "oops" in result.error
|
||||||
assert "Failed to transform tool message:" in result.error
|
assert "Failed to invoke tool" in result.error
|
||||||
assert result.error_type == "ToolInvokeError"
|
assert result.error_type == "ToolInvokeError"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user