Add custom exceptions

This commit is contained in:
2025-09-26 16:15:02 +00:00
parent b44a209d42
commit 250dfa728e
4 changed files with 22 additions and 14 deletions

View File

@@ -42,5 +42,5 @@ asyncio_default_fixture_loop_scope = "function"
extend-exclude = ["tests"] extend-exclude = ["tests"]
[tool.ruff.lint] [tool.ruff.lint]
extend-select = ["I", "D", "ERA", "UP"] extend-select = ["I", "D", "ERA", "UP", "FURB", "TRY", "PERF"]
ignore = ["D203", "D213"] ignore = ["D203", "D213"]

View File

@@ -28,6 +28,14 @@ from typing import Literal, overload
from .qdrant_engine import QdrantEngine from .qdrant_engine import QdrantEngine
class UnknownEngineError(Exception):
"""Exception raised when an unknown engine is requested."""
def __init__(self, backend: str):
"""Initialize the exception with the unknown backend."""
super().__init__(f"Unknown engine type: {backend}")
class Backend(StrEnum): class Backend(StrEnum):
"""Enumeration of supported vector database backends. """Enumeration of supported vector database backends.
@@ -96,4 +104,4 @@ def get_engine(backend: Backend):
elif backend == Backend.COSMOS: elif backend == Backend.COSMOS:
raise NotImplementedError("Cosmos engine is not implemented yet") raise NotImplementedError("Cosmos engine is not implemented yet")
else: else:
raise ValueError(f"Unknown engine type: {backend}") raise UnknownEngineError(backend)

View File

@@ -12,7 +12,7 @@ maintaining a consistent interface for the semantic search workflow.
""" """
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Generic, TypeVar from typing import TypeVar
from ..models import Condition, SearchRow from ..models import Condition, SearchRow
@@ -22,7 +22,7 @@ ConditionType = TypeVar("ConditionType")
__all__ = ["BaseEngine"] __all__ = ["BaseEngine"]
class BaseEngine(ABC, Generic[ResponseType, ConditionType]): class BaseEngine[ResponseType, ConditionType](ABC):
"""Abstract base class for vector search engines. """Abstract base class for vector search engines.
This class defines the interface that all vector search engine implementations This class defines the interface that all vector search engine implementations

View File

@@ -2,7 +2,7 @@ from unittest.mock import MagicMock, patch
import pytest import pytest
from vector_search_mcp.engine import Backend, get_engine from vector_search_mcp.engine import Backend, get_engine, UnknownEngineError
from vector_search_mcp.engine.base_engine import BaseEngine from vector_search_mcp.engine.base_engine import BaseEngine
from vector_search_mcp.engine.qdrant_engine import QdrantEngine from vector_search_mcp.engine.qdrant_engine import QdrantEngine
@@ -52,7 +52,7 @@ class TestEngineFactory:
# Create an invalid engine type (bypassing enum validation) # Create an invalid engine type (bypassing enum validation)
invalid_type = "invalid_engine" invalid_type = "invalid_engine"
with pytest.raises(ValueError, match="Unknown engine type: invalid_engine"): with pytest.raises(UnknownEngineError, match="Unknown engine type: invalid_engine"):
# We need to cast to bypass type checking # We need to cast to bypass type checking
get_engine(invalid_type) # type: ignore get_engine(invalid_type) # type: ignore
@@ -234,22 +234,22 @@ class TestEngineFactoryErrorHandling:
def test_none_backend_type(self): def test_none_backend_type(self):
"""Test get_engine with None raises appropriate error""" """Test get_engine with None raises appropriate error"""
with pytest.raises((TypeError, ValueError)): with pytest.raises((TypeError, UnknownEngineError)):
get_engine(None) # type: ignore get_engine(None) # type: ignore
def test_empty_string_backend_type(self): def test_empty_string_backend_type(self):
"""Test get_engine with empty string""" """Test get_engine with empty string"""
with pytest.raises(ValueError, match="Unknown engine type"): with pytest.raises(UnknownEngineError, match="Unknown engine type"):
get_engine("") # type: ignore get_engine("") # type: ignore
def test_numeric_backend_type(self): def test_numeric_backend_type(self):
"""Test get_engine with numeric input""" """Test get_engine with numeric input"""
with pytest.raises((TypeError, ValueError)): with pytest.raises((TypeError, UnknownEngineError)):
get_engine(123) # type: ignore get_engine(123) # type: ignore
def test_boolean_backend_type(self): def test_boolean_backend_type(self):
"""Test get_engine with boolean input""" """Test get_engine with boolean input"""
with pytest.raises((TypeError, ValueError)): with pytest.raises((TypeError, UnknownEngineError)):
get_engine(True) # type: ignore get_engine(True) # type: ignore
def test_get_engine_cosmos_not_implemented(self): def test_get_engine_cosmos_not_implemented(self):
@@ -273,16 +273,16 @@ class TestEngineFactoryErrorHandling:
def test_case_sensitive_backend_type(self): def test_case_sensitive_backend_type(self):
"""Test that backend type matching is case sensitive""" """Test that backend type matching is case sensitive"""
with pytest.raises(ValueError, match="Unknown engine type"): with pytest.raises(UnknownEngineError, match="Unknown engine type"):
get_engine("QDRANT") # type: ignore get_engine("QDRANT") # type: ignore
with pytest.raises(ValueError, match="Unknown engine type"): with pytest.raises(UnknownEngineError, match="Unknown engine type"):
get_engine("Qdrant") # type: ignore get_engine("Qdrant") # type: ignore
def test_whitespace_backend_type(self): def test_whitespace_backend_type(self):
"""Test backend type with whitespace""" """Test backend type with whitespace"""
with pytest.raises(ValueError, match="Unknown engine type"): with pytest.raises(UnknownEngineError, match="Unknown engine type"):
get_engine(" qdrant ") # type: ignore get_engine(" qdrant ") # type: ignore
with pytest.raises(ValueError, match="Unknown engine type"): with pytest.raises(UnknownEngineError, match="Unknown engine type"):
get_engine("\tqdrant\n") # type: ignore get_engine("\tqdrant\n") # type: ignore