import importlib.util from pathlib import Path import sys import unittest _MODULE_PATH = Path(__file__).parents[1] / "app" / "utils" / "api_errors.py" _SPEC = importlib.util.spec_from_file_location("api_errors_under_test", _MODULE_PATH) assert _SPEC is not None and _SPEC.loader is not None _MODULE = importlib.util.module_from_spec(_SPEC) sys.modules[_SPEC.name] = _MODULE _SPEC.loader.exec_module(_MODULE) ApiError = _MODULE.ApiError internal_error_payload = _MODULE.internal_error_payload class ApiErrorTests(unittest.TestCase): def translator(self, key, **kwargs): return f"{key}:{kwargs.get('id', '')}".rstrip(":") def test_structured_error_has_code_and_localized_message_only(self): error = ApiError( code="project_not_found", status_code=404, message_key="api.projectNotFound", params={"id": "demo"}, ) payload = error.to_payload(self.translator) self.assertEqual(payload, { "success": False, "error_code": "project_not_found", "message": "api.projectNotFound:demo", }) self.assertNotIn("error", payload) self.assertNotIn("details", payload) def test_internal_error_never_contains_exception_text(self): payload = internal_error_payload(self.translator) self.assertEqual(payload["success"], False) self.assertEqual(payload["error_code"], "internal_error") self.assertEqual(payload["message"], "api.internalError") self.assertNotIn("Traceback", str(payload)) self.assertNotIn("secret", str(payload)) if __name__ == "__main__": unittest.main()