mirror of
https://github.com/langgenius/dify.git
synced 2026-04-05 04:59:23 +08:00
feat: return correct dify-plugin-daemon error message (#34171)
This commit is contained in:
@@ -200,7 +200,7 @@ class PluginDebuggingKeyApi(Resource):
|
||||
"port": dify_config.PLUGIN_REMOTE_INSTALL_PORT,
|
||||
}
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/list")
|
||||
@@ -215,7 +215,7 @@ class PluginListApi(Resource):
|
||||
try:
|
||||
plugins_with_total = PluginService.list_with_total(tenant_id, args.page, args.page_size)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
return jsonable_encoder({"plugins": plugins_with_total.list, "total": plugins_with_total.total})
|
||||
|
||||
@@ -232,7 +232,7 @@ class PluginListLatestVersionsApi(Resource):
|
||||
try:
|
||||
versions = PluginService.list_latest_versions(args.plugin_ids)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
return jsonable_encoder({"versions": versions})
|
||||
|
||||
@@ -251,7 +251,7 @@ class PluginListInstallationsFromIdsApi(Resource):
|
||||
try:
|
||||
plugins = PluginService.list_installations_from_ids(tenant_id, args.plugin_ids)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
return jsonable_encoder({"plugins": plugins})
|
||||
|
||||
@@ -266,7 +266,7 @@ class PluginIconApi(Resource):
|
||||
try:
|
||||
icon_bytes, mimetype = PluginService.get_asset(args.tenant_id, args.filename)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
icon_cache_max_age = dify_config.TOOL_ICON_CACHE_MAX_AGE
|
||||
return send_file(io.BytesIO(icon_bytes), mimetype=mimetype, max_age=icon_cache_max_age)
|
||||
@@ -286,7 +286,7 @@ class PluginAssetApi(Resource):
|
||||
binary = PluginService.extract_asset(tenant_id, args.plugin_unique_identifier, args.file_name)
|
||||
return send_file(io.BytesIO(binary), mimetype="application/octet-stream")
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/upload/pkg")
|
||||
@@ -303,7 +303,7 @@ class PluginUploadFromPkgApi(Resource):
|
||||
try:
|
||||
response = PluginService.upload_pkg(tenant_id, content)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
return jsonable_encoder(response)
|
||||
|
||||
@@ -323,7 +323,7 @@ class PluginUploadFromGithubApi(Resource):
|
||||
try:
|
||||
response = PluginService.upload_pkg_from_github(tenant_id, args.repo, args.version, args.package)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
return jsonable_encoder(response)
|
||||
|
||||
@@ -361,7 +361,7 @@ class PluginInstallFromPkgApi(Resource):
|
||||
try:
|
||||
response = PluginService.install_from_local_pkg(tenant_id, args.plugin_unique_identifiers)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
return jsonable_encoder(response)
|
||||
|
||||
@@ -387,7 +387,7 @@ class PluginInstallFromGithubApi(Resource):
|
||||
args.package,
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
return jsonable_encoder(response)
|
||||
|
||||
@@ -407,7 +407,7 @@ class PluginInstallFromMarketplaceApi(Resource):
|
||||
try:
|
||||
response = PluginService.install_from_marketplace_pkg(tenant_id, args.plugin_unique_identifiers)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
return jsonable_encoder(response)
|
||||
|
||||
@@ -433,7 +433,7 @@ class PluginFetchMarketplacePkgApi(Resource):
|
||||
}
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/fetch-manifest")
|
||||
@@ -453,7 +453,7 @@ class PluginFetchManifestApi(Resource):
|
||||
{"manifest": PluginService.fetch_plugin_manifest(tenant_id, args.plugin_unique_identifier).model_dump()}
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/tasks")
|
||||
@@ -471,7 +471,7 @@ class PluginFetchInstallTasksApi(Resource):
|
||||
try:
|
||||
return jsonable_encoder({"tasks": PluginService.fetch_install_tasks(tenant_id, args.page, args.page_size)})
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/tasks/<task_id>")
|
||||
@@ -486,7 +486,7 @@ class PluginFetchInstallTaskApi(Resource):
|
||||
try:
|
||||
return jsonable_encoder({"task": PluginService.fetch_install_task(tenant_id, task_id)})
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/tasks/<task_id>/delete")
|
||||
@@ -501,7 +501,7 @@ class PluginDeleteInstallTaskApi(Resource):
|
||||
try:
|
||||
return {"success": PluginService.delete_install_task(tenant_id, task_id)}
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/tasks/delete_all")
|
||||
@@ -516,7 +516,7 @@ class PluginDeleteAllInstallTaskItemsApi(Resource):
|
||||
try:
|
||||
return {"success": PluginService.delete_all_install_task_items(tenant_id)}
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/tasks/<task_id>/delete/<path:identifier>")
|
||||
@@ -531,7 +531,7 @@ class PluginDeleteInstallTaskItemApi(Resource):
|
||||
try:
|
||||
return {"success": PluginService.delete_install_task_item(tenant_id, task_id, identifier)}
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/upgrade/marketplace")
|
||||
@@ -553,7 +553,7 @@ class PluginUpgradeFromMarketplaceApi(Resource):
|
||||
)
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/upgrade/github")
|
||||
@@ -580,7 +580,7 @@ class PluginUpgradeFromGithubApi(Resource):
|
||||
)
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/uninstall")
|
||||
@@ -598,7 +598,7 @@ class PluginUninstallApi(Resource):
|
||||
try:
|
||||
return {"success": PluginService.uninstall(tenant_id, args.plugin_installation_id)}
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/permission/change")
|
||||
@@ -674,7 +674,7 @@ class PluginFetchDynamicSelectOptionsApi(Resource):
|
||||
provider_type=args.provider_type,
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
return jsonable_encoder({"options": options})
|
||||
|
||||
@@ -705,7 +705,7 @@ class PluginFetchDynamicSelectOptionsWithCredentialsApi(Resource):
|
||||
credentials=args.credentials,
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
return jsonable_encoder({"options": options})
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ from core.plugin.endpoint.exc import EndpointSetupFailedError
|
||||
from core.plugin.entities.plugin_daemon import PluginDaemonBasicResponse, PluginDaemonError, PluginDaemonInnerError
|
||||
from core.plugin.impl.exc import (
|
||||
PluginDaemonBadRequestError,
|
||||
PluginDaemonClientSideError,
|
||||
PluginDaemonInternalServerError,
|
||||
PluginDaemonNotFoundError,
|
||||
PluginDaemonUnauthorizedError,
|
||||
@@ -235,7 +236,10 @@ class BasePluginClient:
|
||||
response.raise_for_status()
|
||||
except httpx.HTTPStatusError as e:
|
||||
logger.exception("Failed to request plugin daemon, status: %s, url: %s", e.response.status_code, path)
|
||||
raise e
|
||||
if e.response.status_code < 500:
|
||||
raise PluginDaemonClientSideError(description=str(e))
|
||||
else:
|
||||
raise PluginDaemonInternalServerError(description=str(e))
|
||||
except Exception as e:
|
||||
msg = f"Failed to request plugin daemon, url: {path}"
|
||||
logger.exception("Failed to request plugin daemon, url: %s", path)
|
||||
|
||||
@@ -90,8 +90,8 @@ class TestPluginListLatestVersionsApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginDebuggingKeyApi:
|
||||
@@ -120,8 +120,8 @@ class TestPluginDebuggingKeyApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginListApi:
|
||||
@@ -202,8 +202,9 @@ class TestPluginUploadFromPkgApi:
|
||||
patch("controllers.console.workspace.plugin.dify_config.PLUGIN_MAX_PACKAGE_SIZE", 0),
|
||||
patch("controllers.console.workspace.plugin.PluginService.upload_pkg") as upload_pkg_mock,
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
method(api)
|
||||
assert "File size exceeds the maximum allowed size" in str(exc_info.value)
|
||||
|
||||
upload_pkg_mock.assert_not_called()
|
||||
|
||||
@@ -365,8 +366,8 @@ class TestPluginListInstallationsFromIdsApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginUploadFromGithubApi:
|
||||
@@ -401,8 +402,8 @@ class TestPluginUploadFromGithubApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginUploadFromBundleApi:
|
||||
@@ -449,8 +450,9 @@ class TestPluginUploadFromBundleApi:
|
||||
patch("controllers.console.workspace.plugin.dify_config.PLUGIN_MAX_BUNDLE_SIZE", 0),
|
||||
patch("controllers.console.workspace.plugin.PluginService.upload_bundle") as upload_bundle_mock,
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
method(api)
|
||||
assert "File size exceeds the maximum allowed size" in str(exc_info.value)
|
||||
|
||||
upload_bundle_mock.assert_not_called()
|
||||
|
||||
@@ -495,8 +497,8 @@ class TestPluginInstallFromGithubApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginInstallFromMarketplaceApi:
|
||||
@@ -532,8 +534,8 @@ class TestPluginInstallFromMarketplaceApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginFetchMarketplacePkgApi:
|
||||
@@ -562,8 +564,8 @@ class TestPluginFetchMarketplacePkgApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginFetchManifestApi:
|
||||
@@ -595,8 +597,8 @@ class TestPluginFetchManifestApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginFetchInstallTasksApi:
|
||||
@@ -625,8 +627,8 @@ class TestPluginFetchInstallTasksApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginFetchInstallTaskApi:
|
||||
@@ -655,8 +657,8 @@ class TestPluginFetchInstallTaskApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api, "t")
|
||||
result = method(api, "t")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginDeleteInstallTaskApi:
|
||||
@@ -685,8 +687,8 @@ class TestPluginDeleteInstallTaskApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api, "t")
|
||||
result = method(api, "t")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginDeleteAllInstallTaskItemsApi:
|
||||
@@ -717,8 +719,8 @@ class TestPluginDeleteAllInstallTaskItemsApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginDeleteInstallTaskItemApi:
|
||||
@@ -747,8 +749,8 @@ class TestPluginDeleteInstallTaskItemApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api, "task1", "item1")
|
||||
result = method(api, "task1", "item1")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginUpgradeFromMarketplaceApi:
|
||||
@@ -790,8 +792,8 @@ class TestPluginUpgradeFromMarketplaceApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginUpgradeFromGithubApi:
|
||||
@@ -839,8 +841,8 @@ class TestPluginUpgradeFromGithubApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginFetchDynamicSelectOptionsWithCredentialsApi:
|
||||
@@ -894,8 +896,8 @@ class TestPluginFetchDynamicSelectOptionsWithCredentialsApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api)
|
||||
result = method(api)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
class TestPluginChangePreferencesApi:
|
||||
|
||||
@@ -26,6 +26,7 @@ from core.plugin.entities.plugin_daemon import (
|
||||
from core.plugin.impl.base import BasePluginClient
|
||||
from core.plugin.impl.exc import (
|
||||
PluginDaemonBadRequestError,
|
||||
PluginDaemonClientSideError,
|
||||
PluginDaemonInternalServerError,
|
||||
PluginDaemonNotFoundError,
|
||||
PluginDaemonUnauthorizedError,
|
||||
@@ -557,7 +558,7 @@ class TestPluginRuntimeErrorHandling:
|
||||
|
||||
with patch("httpx.request", return_value=mock_response, autospec=True):
|
||||
# Act & Assert
|
||||
with pytest.raises(httpx.HTTPStatusError):
|
||||
with pytest.raises(PluginDaemonInternalServerError):
|
||||
plugin_client._request_with_plugin_daemon_response("GET", "plugin/test-tenant/test", bool)
|
||||
|
||||
def test_empty_data_response_error(self, plugin_client, mock_config):
|
||||
@@ -1808,8 +1809,8 @@ class TestPluginInstallerAdvanced:
|
||||
mock_response.raise_for_status = raise_for_status
|
||||
|
||||
with patch("httpx.request", return_value=mock_response, autospec=True):
|
||||
# Act & Assert - Should raise HTTPStatusError for 404
|
||||
with pytest.raises(httpx.HTTPStatusError):
|
||||
# Act & Assert - Should raise PluginDaemonClientSideError for 404
|
||||
with pytest.raises(PluginDaemonClientSideError):
|
||||
installer.fetch_plugin_readme("test-tenant", "test-org/test-plugin", "en")
|
||||
|
||||
def test_list_plugins_with_pagination(self, installer, mock_config):
|
||||
|
||||
Reference in New Issue
Block a user