From 14fbeadbb2a0cc1f7a83567da19f05b192025c00 Mon Sep 17 00:00:00 2001 From: Grzegorz Kostkowski Date: Wed, 8 Jul 2026 09:40:32 +0200 Subject: [PATCH 1/3] chore(logging): disable traceback for controlled exceptions --- src/ere/services/entity_resolution_service.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ere/services/entity_resolution_service.py b/src/ere/services/entity_resolution_service.py index dbc5e36..d013f8a 100644 --- a/src/ere/services/entity_resolution_service.py +++ b/src/ere/services/entity_resolution_service.py @@ -489,9 +489,10 @@ def process_request(self, request: ERERequest) -> EREResponse: timestamp=now, ) except Exception as exc: # pylint: disable=broad-exception-caught - log.exception( - "Resolution error for mention %s", + log.error( + "Resolution error for mention %s: %s", request.ere_request_id, + exc, ) return EREErrorResponse( ere_request_id=request.ere_request_id, From c92dece2467c19f032f66b4849f9ac12d79d0d11 Mon Sep 17 00:00:00 2001 From: Grzegorz Kostkowski Date: Wed, 8 Jul 2026 09:47:28 +0200 Subject: [PATCH 2/3] chore(logging): add NOSONAR suppression for intentional no-traceback log --- src/ere/services/entity_resolution_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ere/services/entity_resolution_service.py b/src/ere/services/entity_resolution_service.py index d013f8a..bbeeac2 100644 --- a/src/ere/services/entity_resolution_service.py +++ b/src/ere/services/entity_resolution_service.py @@ -489,7 +489,7 @@ def process_request(self, request: ERERequest) -> EREResponse: timestamp=now, ) except Exception as exc: # pylint: disable=broad-exception-caught - log.error( + log.error( # NOSONAR - intentionally no traceback; service converts to EREErrorResponse "Resolution error for mention %s: %s", request.ere_request_id, exc, From 88b97f9cbac024c7c4516e7adb1ea7cd9f2c2bad Mon Sep 17 00:00:00 2001 From: Grzegorz Kostkowski Date: Wed, 8 Jul 2026 12:02:12 +0200 Subject: [PATCH 3/3] fix(services): two-tier exception handling in process_request Controlled exceptions (ValueError, ConflictError) are logged with log.error (no traceback, typed response). Uncontrolled exceptions are caught as fallback with log.exception (full traceback, generic InternalError response). Adds top-level ConflictError import. --- src/ere/services/entity_resolution_service.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/ere/services/entity_resolution_service.py b/src/ere/services/entity_resolution_service.py index bbeeac2..d5a05cd 100644 --- a/src/ere/services/entity_resolution_service.py +++ b/src/ere/services/entity_resolution_service.py @@ -20,6 +20,7 @@ MentionRepository, SimilarityRepository, ) +from ere.models.exceptions import ConflictError from ere.models.resolver import ( CandidateCluster, ClusterId, @@ -229,8 +230,6 @@ def check_conflict(self, mention: Mention) -> None: Raises: ConflictError: If mention_id already exists with different attributes. """ - from ere.models.exceptions import ConflictError - existing = self._mention_repo.find_by_id(mention.id) if existing is not None and existing.attributes != mention.attributes: raise ConflictError( @@ -488,8 +487,8 @@ def process_request(self, request: ERERequest) -> EREResponse: ere_request_id=request.ere_request_id, timestamp=now, ) - except Exception as exc: # pylint: disable=broad-exception-caught - log.error( # NOSONAR - intentionally no traceback; service converts to EREErrorResponse + except (ValueError, ConflictError) as exc: + log.error( # NOSONAR - intentionally no traceback for controlled exceptions "Resolution error for mention %s: %s", request.ere_request_id, exc, @@ -501,6 +500,18 @@ def process_request(self, request: ERERequest) -> EREResponse: error_detail=str(exc), timestamp=now, ) + except Exception: # pylint: disable=broad-exception-caught + log.exception( + "Unexpected error for mention %s", + request.ere_request_id, + ) + return EREErrorResponse( + ere_request_id=request.ere_request_id, + error_type="InternalError", + error_title="Unexpected error", + error_detail="An unexpected error occurred", + timestamp=now, + ) def __call__(self, request: ERERequest) -> EREResponse: """Make the service callable."""