diff --git a/swh/search/api/client.py b/swh/search/api/client.py --- a/swh/search/api/client.py +++ b/swh/search/api/client.py @@ -1,10 +1,11 @@ -# Copyright (C) 2019-2020 The Software Heritage developers +# Copyright (C) 2019-2022 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information from swh.core.api import RPCClient +from .. import exc from ..interface import SearchInterface @@ -12,3 +13,4 @@ """Proxy to a remote search API""" backend_class = SearchInterface + reraise_exceptions = [getattr(exc, exc_name) for exc_name in exc.__all__] diff --git a/swh/search/exc.py b/swh/search/exc.py new file mode 100644 --- /dev/null +++ b/swh/search/exc.py @@ -0,0 +1,18 @@ +# Copyright (C) 2022 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +__all__ = ("SearchException", "SearchQuerySyntaxError") + + +class SearchException(Exception): + """Base exception for errors specific to swh-search""" + + pass + + +class SearchQuerySyntaxError(SearchException): + """Raised when the 'query' argument of origin_search cannot be parsed""" + + pass diff --git a/swh/search/tests/test_elasticsearch.py b/swh/search/tests/test_elasticsearch.py --- a/swh/search/tests/test_elasticsearch.py +++ b/swh/search/tests/test_elasticsearch.py @@ -1,4 +1,4 @@ -# Copyright (C) 2019-2021 The Software Heritage developers +# Copyright (C) 2019-2022 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -11,6 +11,7 @@ from elasticsearch.helpers.errors import BulkIndexError import pytest +from swh.search.exc import SearchQuerySyntaxError from swh.search.metrics import OPERATIONS_METRIC from .test_search import CommonSearchTest @@ -165,3 +166,14 @@ _check_results("sort_by = [-visits] limit = 1", [2]) _check_results("sort_by = [last_visit] and limit = 2", [0, 1]) _check_results("sort_by = [-last_eventful_visit, visits] limit = 3", [1, 0, 2]) + + def test_query_syntax_error(self): + ORIGINS = [ + {"url": "http://foobar.1.com",}, + ] + + self.search.origin_update(ORIGINS) + self.search.flush() + + with pytest.raises(SearchQuerySyntaxError): + self.search.origin_search(query="foobar") diff --git a/swh/search/translator.py b/swh/search/translator.py --- a/swh/search/translator.py +++ b/swh/search/translator.py @@ -10,6 +10,7 @@ from pkg_resources import resource_filename from tree_sitter import Language, Parser +from swh.search.exc import SearchQuerySyntaxError from swh.search.utils import get_expansion, unescape logger = logging.getLogger(__name__) @@ -45,7 +46,7 @@ self.query_node = tree.root_node if self.query_node.has_error: - raise Exception("Invalid query") + raise SearchQuerySyntaxError("Invalid query") return self._traverse(self.query_node) @@ -304,4 +305,4 @@ if category == "limit": return value - raise Exception(f"Unknown filter {category}.{name}") + raise SearchQuerySyntaxError(f"Unknown filter {category}.{name}")