forked from innovacion/searchbox
Add custom exceptions
This commit is contained in:
@@ -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"]
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user