This is an automated email from the ASF dual-hosted git repository. iilyak pushed a commit to branch improve-errors-in-mango-tests in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 9cdb361f5febc4279e6d039efd1693d672bf11c8 Author: ILYA Khlopotov <[email protected]> AuthorDate: Thu Sep 18 11:57:35 2025 -0700 Print response body on errors from mango test suite Add `body` to error messages do error would look like ``` ====================================================================== ERROR: test_group_field_number_is_unsupported (99-test_query.TestQuery.test_group_field_number_is_unsupported) ---------------------------------------------------------------------- Traceback (most recent call last): File "~/Code/couchdb/src/mango/test/99-test_query.py", line 163, in test_group_field_number_is_unsupported self.db.create_text_index(name="animals") File "~/Code/couchdb/src/mango/test/mango.py", line 261, in create_text_index raise_for_status(r) File "~/Code/couchdb/src/mango/test/mango.py", line 102, in raise_for_status raise SearchException(err) from None mango.SearchException: 503 Server Error: Service Unavailable for url: http://127.0.0.1:15984/mango_test_123c0654f1e84db7aed9d380062d8131/_index body: {"error":"required index service unavailable","reason":"text"} ``` --- src/mango/test/02-basic-find-test.py | 2 +- src/mango/test/mango.py | 38 ++++++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/mango/test/02-basic-find-test.py b/src/mango/test/02-basic-find-test.py index 9a701b06d..cae772b8a 100644 --- a/src/mango/test/02-basic-find-test.py +++ b/src/mango/test/02-basic-find-test.py @@ -139,7 +139,7 @@ class BasicFindTests(mango.UserDocsTests): '"location.city":{"$exists":true}}}' ) r = self.db.sess.post(self.db.path("_find"), data=body) - r.raise_for_status() + mango.raise_for_status(r) docs = r.json()["docs"] # expectation is that only the second instance diff --git a/src/mango/test/mango.py b/src/mango/test/mango.py index f0a8b1582..972bbd4aa 100644 --- a/src/mango/test/mango.py +++ b/src/mango/test/mango.py @@ -25,6 +25,15 @@ import friend_docs import user_docs import limit_docs +class SearchException(requests.exceptions.HTTPError): + def __init__(self, err: requests.exceptions.HTTPError): + super().__init__(str(err), response=err.response) + self.request = err.request + self.response = err.response + def __str__(self): + formatted = super().__str__() + body = "body: {}".format(self.response.text) + return '\n'.join([formatted, body]) COUCH_HOST = os.environ.get("COUCH_HOST") or "http://127.0.0.1:15984" COUCH_USER = os.environ.get("COUCH_USER") @@ -65,6 +74,11 @@ def delay(n=5, t=0.5): for i in range(0, n): time.sleep(t) +def raise_for_status(resp): + try: + resp.raise_for_status() + except requests.exceptions.HTTPError as err: + raise SearchException(err) from None class Concurrently(object): def __init__(self, thread, thread_args, start=True): @@ -108,11 +122,11 @@ class Database(object): if r.status_code == 404: p = str(partitioned).lower() r = self.sess.put(self.url, params={"q": q, "n": n, "partitioned": p}) - r.raise_for_status() + raise_for_status(r) def delete(self): r = self.sess.delete(self.url) - r.raise_for_status() + raise_for_status(r) def recreate(self): r = self.sess.get(self.url) @@ -132,32 +146,32 @@ class Database(object): def save_docs_with_conflicts(self, docs, **kwargs): body = json.dumps({"docs": docs, "new_edits": False}) r = self.sess.post(self.path("_bulk_docs"), data=body, params=kwargs) - r.raise_for_status() + raise_for_status(r) def save_docs(self, docs, **kwargs): for offset in range(0, len(docs), BULK_BATCH_SIZE): chunk = docs[offset : (offset + BULK_BATCH_SIZE)] body = {"docs": chunk} r = self.sess.post(self.path("_bulk_docs"), json=body, params=kwargs) - r.raise_for_status() + raise_for_status(r) for doc, result in zip(chunk, r.json()): doc["_id"] = result["id"] doc["_rev"] = result["rev"] def open_doc(self, docid): r = self.sess.get(self.path(docid)) - r.raise_for_status() + raise_for_status(r) return r.json() def delete_doc(self, docid): r = self.sess.get(self.path(docid)) - r.raise_for_status() + raise_for_status(r) original_rev = r.json()["_rev"] self.sess.delete(self.path(docid), params={"rev": original_rev}) def ddoc_info(self, ddocid): r = self.sess.get(self.path([ddocid, "_info"])) - r.raise_for_status() + raise_for_status(r) return r.json() def create_index( @@ -180,7 +194,7 @@ class Database(object): body["index"]["partial_filter_selector"] = partial_filter_selector body = json.dumps(body) r = self.sess.post(self.path("_index"), data=body) - r.raise_for_status() + raise_for_status(r) assert r.json()["id"] is not None assert r.json()["name"] is not None @@ -223,7 +237,7 @@ class Database(object): body["ddoc"] = ddoc body = json.dumps(body) r = self.sess.post(self.path("_index"), data=body) - r.raise_for_status() + raise_for_status(r) return r.json()["result"] == "created" def list_indexes(self, limit="", skip=""): @@ -232,7 +246,7 @@ class Database(object): if skip != "": skip = "skip=" + str(skip) r = self.sess.get(self.path("_index?" + limit + ";" + skip)) - r.raise_for_status() + raise_for_status(r) return r.json()["indexes"] def get_index(self, ddocid, name): @@ -255,7 +269,7 @@ class Database(object): def delete_index(self, ddocid, name, idx_type="json"): path = ["_index", ddocid, idx_type, name] r = self.sess.delete(self.path(path), params={"w": "3"}) - r.raise_for_status() + raise_for_status(r) while len(self.get_index(ddocid, name)) == 1: delay(t=0.1) @@ -314,7 +328,7 @@ class Database(object): else: path = self.path("{}_find".format(ppath)) r = self.sess.post(path, data=body) - r.raise_for_status() + raise_for_status(r) if explain or return_raw: return r.json() else:
