diff --git a/lua/vectorcode/integrations/codecompanion/query_tool.lua b/lua/vectorcode/integrations/codecompanion/query_tool.lua index 9f893ce9..f02de129 100644 --- a/lua/vectorcode/integrations/codecompanion/query_tool.lua +++ b/lua/vectorcode/integrations/codecompanion/query_tool.lua @@ -181,10 +181,30 @@ For example, you should include `parameter`, `arguments` and `return value` for ) ) stderr = cc_common.flatten_table_to_string(stderr) - agent.chat:add_tool_output( - self, - string.format("**VectorCode Tool**: Failed with error:\n```\n%s\n```", stderr) - ) + if string.find(stderr, "InvalidCollectionException") then + if cmd.project_root then + agent.chat:add_tool_output( + self, + string.format( + "`%s` hasn't been vectorised. Please use the `vectorcode_vectorise` tool or vectorise it from the CLI.", + cmd.project_root + ) + ) + else + agent.chat:add_tool_output( + self, + "Failed to query from the requested project. Please verify the available projects via the `vectorcode_ls` tool or run it from the CLI." + ) + end + else + agent.chat:add_tool_output( + self, + string.format( + "**VectorCode `query` Tool**: Failed with error:\n```\n%s\n```", + stderr + ) + ) + end end, ---@param agent CodeCompanion.Agent ---@param cmd QueryToolArgs diff --git a/src/vectorcode/lsp_main.py b/src/vectorcode/lsp_main.py index 9be676f0..f6fae6d1 100644 --- a/src/vectorcode/lsp_main.py +++ b/src/vectorcode/lsp_main.py @@ -25,9 +25,9 @@ JsonRpcInvalidRequest, ) from pygls.server import LanguageServer -except ModuleNotFoundError: # pragma: nocover +except ModuleNotFoundError as e: # pragma: nocover print( - "Please install the `vectorcode[lsp]` dependency group to use the LSP feature.", + f"{e.__class__.__name__}: Please install the `vectorcode[lsp]` dependency group to use the LSP feature.", file=sys.stderr, ) sys.exit(1) diff --git a/src/vectorcode/main.py b/src/vectorcode/main.py index b86f983a..3ea8eefa 100644 --- a/src/vectorcode/main.py +++ b/src/vectorcode/main.py @@ -69,10 +69,10 @@ async def async_main(): if not await try_server(final_configs.db_url): server_process = await start_server(final_configs) - if final_configs.pipe: + if final_configs.pipe: # pragma: nocover # NOTE: NNCF (intel GPU acceleration for sentence transformer) keeps showing logs. # This disables logs below ERROR so that it doesn't hurt the `pipe` output. - logging.disable(logging.ERROR) + logging.disable(logging.ERROR - 1) return_val = 0 try: diff --git a/src/vectorcode/mcp_main.py b/src/vectorcode/mcp_main.py index d9df8645..da97a69a 100644 --- a/src/vectorcode/mcp_main.py +++ b/src/vectorcode/mcp_main.py @@ -15,9 +15,9 @@ try: # pragma: nocover from mcp import ErrorData, McpError from mcp.server.fastmcp import FastMCP -except ModuleNotFoundError: # pragma: nocover +except ModuleNotFoundError as e: # pragma: nocover print( - "MCP Python SDK not installed. Please install it by installing `vectorcode[mcp]` dependency group.", + f"{e.__class__.__name__}:MCP Python SDK not installed. Please install it by installing `vectorcode[mcp]` dependency group.", file=sys.stderr, ) sys.exit(1) @@ -114,12 +114,12 @@ async def query_tool( try: client = await get_client(config) collection = await get_collection(client, config, False) - except Exception: + except Exception as e: logger.error("Failed to access collection at %s", project_root) raise McpError( ErrorData( code=1, - message=f"Failed to access the collection at {project_root}. Use `list_collections` tool to get a list of valid paths for this field.", + message=f"{e.__class__.__name__}: Failed to access the collection at {project_root}. Use `list_collections` tool to get a list of valid paths for this field.", ) ) if collection is None: diff --git a/src/vectorcode/subcommands/drop.py b/src/vectorcode/subcommands/drop.py index 20fb7594..08fbbbae 100644 --- a/src/vectorcode/subcommands/drop.py +++ b/src/vectorcode/subcommands/drop.py @@ -17,6 +17,8 @@ async def drop(config: Config) -> int: print(f"Collection for {collection_path} has been deleted.") logger.info(f"Deteted collection at {collection_path}.") return 0 - except (ValueError, InvalidCollectionException): - logger.error(f"There's no existing collection for {config.project_root}") + except (ValueError, InvalidCollectionException) as e: + logger.error( + f"{e.__class__.__name__}: There's no existing collection for {config.project_root}" + ) return 1 diff --git a/src/vectorcode/subcommands/query/__init__.py b/src/vectorcode/subcommands/query/__init__.py index e29eab2f..0341772b 100644 --- a/src/vectorcode/subcommands/query/__init__.py +++ b/src/vectorcode/subcommands/query/__init__.py @@ -159,18 +159,20 @@ async def query(configs: Config) -> int: collection = await get_collection(client, configs, False) if not verify_ef(collection, configs): return 1 - except (ValueError, InvalidCollectionException): + except (ValueError, InvalidCollectionException) as e: logger.error( - f"There's no existing collection for {configs.project_root}", + f"{e.__class__.__name__}: There's no existing collection for {configs.project_root}", ) return 1 - except InvalidDimensionException: + except InvalidDimensionException as e: logger.error( - "The collection was embedded with a different embedding model.", + f"{e.__class__.__name__}: The collection was embedded with a different embedding model.", ) return 1 - except IndexError: # pragma: nocover - logger.error("Failed to get the collection. Please check your config.") + except IndexError as e: # pragma: nocover + logger.error( + f"{e.__class__.__name__}: Failed to get the collection. Please check your config." + ) return 1 if not configs.pipe: @@ -187,8 +189,9 @@ async def query(configs: Config) -> int: try: structured_result = await build_query_results(collection, configs) - except RerankerError: # pragma: nocover + except RerankerError as e: # pragma: nocover # error logs should be handled where they're raised + logger.error(f"{e.__class__.__name__}") return 1 if configs.pipe: diff --git a/src/vectorcode/subcommands/update.py b/src/vectorcode/subcommands/update.py index 41578eeb..2d7d4322 100644 --- a/src/vectorcode/subcommands/update.py +++ b/src/vectorcode/subcommands/update.py @@ -19,12 +19,14 @@ async def update(configs: Config) -> int: client = await get_client(configs) try: collection = await get_collection(client, configs, False) - except IndexError: - print("Failed to get/create the collection. Please check your config.") + except IndexError as e: + print( + f"{e.__class__.__name__}: Failed to get/create the collection. Please check your config." + ) return 1 - except (ValueError, InvalidCollectionException): + except (ValueError, InvalidCollectionException) as e: print( - f"There's no existing collection for {configs.project_root}", + f"{e.__class__.__name__}: There's no existing collection for {configs.project_root}", file=sys.stderr, ) return 1 diff --git a/src/vectorcode/subcommands/vectorise.py b/src/vectorcode/subcommands/vectorise.py index ebaa2f6c..e1c61dbb 100644 --- a/src/vectorcode/subcommands/vectorise.py +++ b/src/vectorcode/subcommands/vectorise.py @@ -230,8 +230,10 @@ async def vectorise(configs: Config) -> int: client = await get_client(configs) try: collection = await get_collection(client, configs, True) - except IndexError: - print("Failed to get/create the collection. Please check your config.") + except IndexError as e: + print( + f"{e.__class__.__name__}: Failed to get/create the collection. Please check your config." + ) return 1 if not verify_ef(collection, configs): return 1 diff --git a/tests/test_main.py b/tests/test_main.py index 4abb2807..d6eadd0b 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -166,24 +166,6 @@ async def test_async_main_try_server_unavailable(monkeypatch): mock_start_server.assert_called_once_with(mock_final_configs) -@pytest.mark.asyncio -async def test_async_main_pipe_logging_disabled(monkeypatch): - mock_cli_args = MagicMock(no_stderr=False, project_root=".", action=CliAction.query) - monkeypatch.setattr( - "vectorcode.main.parse_cli_args", AsyncMock(return_value=mock_cli_args) - ) - MagicMock(host="test_host", port=1234, action=CliAction.query, pipe=True) - monkeypatch.setattr("vectorcode.main.get_project_config", AsyncMock()) - monkeypatch.setattr("vectorcode.common.try_server", AsyncMock(return_value=True)) - monkeypatch.setattr("vectorcode.subcommands.query", AsyncMock(return_value=0)) - - with patch("logging.disable") as mock_logging_disable: - await async_main() - mock_logging_disable.assert_called_once_with( - pytest.importorskip("logging").ERROR - ) - - @pytest.mark.asyncio async def test_async_main_cli_action_query(monkeypatch): mock_cli_args = MagicMock(no_stderr=False, project_root=".", action=CliAction.query) diff --git a/tests/test_mcp.py b/tests/test_mcp.py index a822dd87..004e92dc 100644 --- a/tests/test_mcp.py +++ b/tests/test_mcp.py @@ -141,8 +141,8 @@ async def test_query_tool_collection_access_failure(): assert exc_info.value.error.code == 1 assert ( - exc_info.value.error.message - == "Failed to access the collection at /valid/path. Use `list_collections` tool to get a list of valid paths for this field." + "Failed to access the collection at /valid/path. Use `list_collections` tool to get a list of valid paths for this field." + in exc_info.value.error.message )