Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F9336854
D8356.id30166.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Subscribers
None
D8356.id30166.diff
View Options
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
Details
Attached
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
Attached To
D8356: Add a centralized error handler
Event Timeline
Log In to Comment