From 28dd0ad50c2902c04bed09637df7f2d9d1fefa7c Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Thu, 17 Apr 2025 17:28:22 +0400 Subject: [PATCH 1/3] Surface caused_by in ApiError In particular, this will give a clear error when using elasticsearch-py 9.0.0 on an 8.x clusters. --- elasticsearch/exceptions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/elasticsearch/exceptions.py b/elasticsearch/exceptions.py index dc410ae30..1efe2ee16 100644 --- a/elasticsearch/exceptions.py +++ b/elasticsearch/exceptions.py @@ -61,6 +61,7 @@ def __str__(self) -> str: if self.body and isinstance(self.body, dict) and "error" in self.body: if isinstance(self.body["error"], dict): root_cause = self.body["error"]["root_cause"][0] + caused_by = self.body["error"].get("caused_by") cause = ", ".join( filter( None, @@ -68,6 +69,7 @@ def __str__(self) -> str: repr(root_cause["reason"]), root_cause.get("resource.id"), root_cause.get("resource.type"), + caused_by.get("reason"), ], ) ) From 23da3412bba92724bb91749feb9e9ee16067313d Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Thu, 17 Apr 2025 17:35:06 +0400 Subject: [PATCH 2/3] Fix lint --- elasticsearch/exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elasticsearch/exceptions.py b/elasticsearch/exceptions.py index 1efe2ee16..70738d5af 100644 --- a/elasticsearch/exceptions.py +++ b/elasticsearch/exceptions.py @@ -61,7 +61,7 @@ def __str__(self) -> str: if self.body and isinstance(self.body, dict) and "error" in self.body: if isinstance(self.body["error"], dict): root_cause = self.body["error"]["root_cause"][0] - caused_by = self.body["error"].get("caused_by") + caused_by = self.body["error"].get("caused_by", {}) cause = ", ".join( filter( None, From 4f84a701ea193b5429c297b67eb0971b11ead3f7 Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Fri, 18 Apr 2025 10:51:06 +0400 Subject: [PATCH 3/3] Add test --- test_elasticsearch/test_exceptions.py | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test_elasticsearch/test_exceptions.py b/test_elasticsearch/test_exceptions.py index 00e8015c7..938aded3d 100644 --- a/test_elasticsearch/test_exceptions.py +++ b/test_elasticsearch/test_exceptions.py @@ -46,3 +46,33 @@ def test_transform_error_parse_with_error_string(self): assert ( str(e) == "ApiError(500, 'InternalServerError', 'something error message')" ) + + def test_transform_invalid_media_type_error(self): + e = ApiError( + message="InvalidMediaType", + meta=error_meta, + body={ + "error": { + "root_cause": [ + { + "type": "media_type_header_exception", + "reason": "Invalid media-type value on headers [Accept, Content-Type]", + } + ], + "type": "media_type_header_exception", + "reason": "Invalid media-type value on headers [Accept, Content-Type]", + "caused_by": { + "type": "status_exception", + "reason": "Accept version must be either version 8 or 7, but found 9. Accept=application/vnd.elasticsearch+json; compatible-with=9", + }, + }, + "status": 400, + }, + ) + + assert str(e) == ( + "ApiError(500, 'InvalidMediaType', " + "'Invalid media-type value on headers [Accept, Content-Type]', " + "Accept version must be either version 8 or 7, but found 9. " + "Accept=application/vnd.elasticsearch+json; compatible-with=9)" + )