Page MenuHomeSoftware Heritage

D8356.id30166.diff
No OneTemporary

D8356.id30166.diff

diff --git a/config/staging.yml b/config/staging.yml
--- a/config/staging.yml
+++ b/config/staging.yml
@@ -6,6 +6,6 @@
cls: remote
url: http://webapp.internal.staging.swh.network:5010
-debug: yes
+debug: no
server-type: wsgi
diff --git a/swh/graphql/errors/__init__.py b/swh/graphql/errors/__init__.py
--- a/swh/graphql/errors/__init__.py
+++ b/swh/graphql/errors/__init__.py
@@ -3,7 +3,12 @@
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information
-from .errors import ObjectNotFoundError, PaginationError
+from .errors import InvalidInputError, ObjectNotFoundError, PaginationError
from .handlers import format_error
-__all__ = ["ObjectNotFoundError", "PaginationError", "format_error"]
+__all__ = [
+ "ObjectNotFoundError",
+ "PaginationError",
+ "InvalidInputError",
+ "format_error",
+]
diff --git a/swh/graphql/errors/errors.py b/swh/graphql/errors/errors.py
--- a/swh/graphql/errors/errors.py
+++ b/swh/graphql/errors/errors.py
@@ -7,6 +7,11 @@
class ObjectNotFoundError(Exception):
""" """
+ msg: str = "Object error"
+
+ def __init__(self, message, errors=None):
+ super().__init__(f"{self.msg}: {message}")
+
class PaginationError(Exception):
""" """
@@ -14,5 +19,13 @@
msg: str = "Pagination error"
def __init__(self, message, errors=None):
- # FIXME, log this error
+ super().__init__(f"{self.msg}: {message}")
+
+
+class InvalidInputError(Exception):
+ """ """
+
+ msg: str = "Input error"
+
+ def __init__(self, message, errors=None):
super().__init__(f"{self.msg}: {message}")
diff --git a/swh/graphql/errors/handlers.py b/swh/graphql/errors/handlers.py
--- a/swh/graphql/errors/handlers.py
+++ b/swh/graphql/errors/handlers.py
@@ -3,11 +3,26 @@
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information
+from ariadne import format_error as original_format_error
+from graphql import GraphQLError
-def format_error(error) -> dict:
+from .errors import InvalidInputError, ObjectNotFoundError, PaginationError
+
+
+def format_error(error: GraphQLError, debug: bool = False):
"""
Response error formatting
"""
+ original_format = original_format_error(error, debug)
+ if debug:
+ # If debug is enabled, reuse Ariadne's formatting logic with stack trace
+ return original_format
+
+ expected_errors = [ObjectNotFoundError, PaginationError, InvalidInputError]
formatted = error.formatted
- formatted["message"] = "Unknown error"
+ formatted["message"] = error.message
+ if error.original_error.__class__ not in expected_errors:
+ # a crash, send original_format to sentry (with stack trace)
+ pass
+ # log the original_format to kibana (with stack trace)
return formatted
diff --git a/swh/graphql/resolvers/scalars.py b/swh/graphql/resolvers/scalars.py
--- a/swh/graphql/resolvers/scalars.py
+++ b/swh/graphql/resolvers/scalars.py
@@ -7,6 +7,7 @@
from ariadne import ScalarType
+from swh.graphql.errors import InvalidInputError
from swh.graphql.utils import utils
from swh.model import hashutil
from swh.model.model import TimestampWithTimezone
@@ -51,10 +52,8 @@
hash_type, hash_string = value.split(":")
hash_value = hashutil.hash_to_bytes(hash_string)
except ValueError as e:
- # FIXME, log this error
- raise AttributeError("Invalid content checksum", e)
+ raise InvalidInputError("Invalid content checksum", e)
except Exception as e:
- # FIXME, log this error
- raise AttributeError("Invalid content checksum", e)
+ raise InvalidInputError("Invalid content checksum", e)
# FIXME, add validation for the hash_type
return hash_type, hash_value
diff --git a/swh/graphql/server.py b/swh/graphql/server.py
--- a/swh/graphql/server.py
+++ b/swh/graphql/server.py
@@ -63,6 +63,7 @@
configuration path to load.
"""
from .app import schema
+ from .errors.handlers import format_error
global graphql_cfg
@@ -77,12 +78,14 @@
# Enable cors in the asgi version
application = CORSMiddleware(
- GraphQL(schema),
+ GraphQL(schema, debug=graphql_cfg["debug"], error_formatter=format_error),
allow_origins=["*"],
allow_methods=("GET", "POST", "OPTIONS"),
)
else:
from ariadne.wsgi import GraphQL
- application = GraphQL(schema)
+ application = GraphQL(
+ schema, debug=graphql_cfg["debug"], error_formatter=format_error
+ )
return application
diff --git a/swh/graphql/tests/functional/test_content.py b/swh/graphql/tests/functional/test_content.py
--- a/swh/graphql/tests/functional/test_content.py
+++ b/swh/graphql/tests/functional/test_content.py
@@ -117,7 +117,7 @@
)
# API will throw an error in case of an invalid content hash
assert len(errors) == 1
- assert "Invalid content checksum" in errors[0]["message"]
+ assert "Input error: Invalid content checksum" in errors[0]["message"]
def test_get_content_as_target(client):
diff --git a/swh/graphql/tests/functional/utils.py b/swh/graphql/tests/functional/utils.py
--- a/swh/graphql/tests/functional/utils.py
+++ b/swh/graphql/tests/functional/utils.py
@@ -22,7 +22,7 @@
data, errors = get_query_response(client, query_str)
assert data[obj_type] is None
assert len(errors) == 1
- assert errors[0]["message"] == "Requested object is not available"
+ assert errors[0]["message"] == "Object error: Requested object is not available"
def get_error_response(client, query_str: str, error_code: int = 400) -> Dict:

File Metadata

Mime Type
text/plain
Expires
Jul 3 2025, 7:46 AM (10 w, 6 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3218790

Event Timeline