diff --git a/frappe/tests/test_api.py b/frappe/tests/test_api.py index 08a240717e..7458ae5d09 100644 --- a/frappe/tests/test_api.py +++ b/frappe/tests/test_api.py @@ -318,6 +318,35 @@ class TestMethodAPIV1(FrappeAPITestCase): response = self.get(self.resource_path("User", "NonExistent@s.com"), {"sid": self.sid}) self.assertEqual(response.status_code, 404) + def test_logs(self): + method = "frappe.tests.test_api.test" + + def get_message(resp, msg_type): + return frappe.parse_json(frappe.parse_json(frappe.parse_json(resp.json)[msg_type])[0]) + + expected_message = "Failed" + response = self.get(self.method_path(method), {"sid": self.sid, "message": expected_message}) + self.assertEqual(get_message(response, "_server_messages").message, expected_message) + + # Cause handled failured + with suppress_stdout(): + response = self.get( + self.method_path(method), {"sid": self.sid, "message": expected_message, "fail": True} + ) + self.assertEqual(get_message(response, "_server_messages").message, expected_message) + self.assertEqual(response.json["exc_type"], "ValidationError") + self.assertIn("Traceback", response.json["exc"]) + + # Cause handled failured + with suppress_stdout(): + response = self.get( + self.method_path(method), + {"sid": self.sid, "message": expected_message, "fail": True, "handled": False}, + ) + self.assertNotIn("_server_messages", response.json) + self.assertIn("ZeroDivisionError", response.json["exception"]) # WHY? + self.assertIn("Traceback", response.json["exc"]) + class TestDocumentAPIV2(TestResourceAPI): version = "v2" @@ -423,6 +452,35 @@ class TestMethodAPIV2(FrappeAPITestCase): ) self.assertEqual(response.status_code, 200) + def test_logs(self): + method = "frappe.tests.test_api.test" + + def get_message(resp, msg_type): + return frappe.parse_json(frappe.parse_json(frappe.parse_json(resp.json)[msg_type])[0]) + + expected_message = "Failed" + response = self.get(self.method_path(method), {"sid": self.sid, "message": expected_message}) + self.assertEqual(get_message(response, "_server_messages").message, expected_message) + + # Cause handled failured + with suppress_stdout(): + response = self.get( + self.method_path(method), {"sid": self.sid, "message": expected_message, "fail": True} + ) + self.assertEqual(get_message(response, "_server_messages").message, expected_message) + self.assertEqual(response.json["exc_type"], "ValidationError") + self.assertIn("Traceback", response.json["exc"]) + + # Cause handled failured + with suppress_stdout(): + response = self.get( + self.method_path(method), + {"sid": self.sid, "message": expected_message, "fail": True, "handled": False}, + ) + self.assertNotIn("_server_messages", response.json) + self.assertIn("ZeroDivisionError", response.json["exception"]) # WHY? + self.assertIn("Traceback", response.json["exc"]) + class TestDocTypeAPIV2(FrappeAPITestCase): version = "v2" @@ -544,3 +602,14 @@ def generate_admin_keys(): generate_keys("Administrator") frappe.db.commit() + + +@frappe.whitelist() +def test(*, fail=False, handled=True, message="Failed"): + if fail: + if handled: + frappe.throw(message) + else: + 1 / 0 + else: + frappe.msgprint(message) diff --git a/frappe/utils/response.py b/frappe/utils/response.py index fcd7b49a0f..d6cea3775f 100644 --- a/frappe/utils/response.py +++ b/frappe/utils/response.py @@ -126,6 +126,7 @@ def as_binary(): def make_logs(response=None): + # TODO: v2 API """make strings for msgprint and errprint""" from frappe.utils.error import guess_exception_source