From 246208dad3dba9d777fd184124f4617952c763f8 Mon Sep 17 00:00:00 2001 From: harshit078 Date: Fri, 7 Mar 2025 16:06:48 +0530 Subject: [PATCH 1/8] Added Json error handling instead of HTML and improved error fetching method --- backend/analytics_server/app.py | 41 +++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/backend/analytics_server/app.py b/backend/analytics_server/app.py index c246a9c8..4af1801c 100644 --- a/backend/analytics_server/app.py +++ b/backend/analytics_server/app.py @@ -1,6 +1,8 @@ from os import getenv -from flask import Flask +from flask import Flask, jsonify, request +from werkzeug.exceptions import HTTPException +import traceback from env import load_app_env @@ -36,5 +38,40 @@ configure_db_with_app(app) initialize_database(app) +# HTTP Error handler +@app.errorhandler(HTTPException) +def handle_http_exception(e): + """Handle HTTP exceptions by returning JSON""" + response = jsonify({ + "error": True, + "message": e.description, + "status_code": e.code, + "path": request.path + }) + response.status_code = e.code + return response + +# Error handler +@app.errorhandler(Exception) +def handle_exception(e): + """Handle non-HTTP exceptions by returning JSON""" + error_details = { + "error": True, + "message": str(e) or "Internal Server Error", + "status_code": 500, + "path": request.path, + "exception_type": e.__class__.__name__ + } + + if app.debug: + error_details["traceback"] = traceback.format_exc() + + response = jsonify(error_details) + response.status_code = 500 + return response + +app.register_error_handler(Exception, handle_exception) +app.register_error_handler(HTTPException, handle_http_exception) + if __name__ == "__main__": - app.run(port=ANALYTICS_SERVER_PORT) + app.run(port=int(ANALYTICS_SERVER_PORT)) From f0fe5ed7098eb6d285b0c70318a983a17e1c8b24 Mon Sep 17 00:00:00 2001 From: harshit078 Date: Fri, 7 Mar 2025 16:35:13 +0530 Subject: [PATCH 2/8] Removed Message and improved Error format --- backend/analytics_server/app.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/backend/analytics_server/app.py b/backend/analytics_server/app.py index 4af1801c..7be31d4d 100644 --- a/backend/analytics_server/app.py +++ b/backend/analytics_server/app.py @@ -43,8 +43,7 @@ def handle_http_exception(e): """Handle HTTP exceptions by returning JSON""" response = jsonify({ - "error": True, - "message": e.description, + "error": e.description, "status_code": e.code, "path": request.path }) @@ -56,8 +55,7 @@ def handle_http_exception(e): def handle_exception(e): """Handle non-HTTP exceptions by returning JSON""" error_details = { - "error": True, - "message": str(e) or "Internal Server Error", + "error": str(e) or "Internal Server Error", "status_code": 500, "path": request.path, "exception_type": e.__class__.__name__ From 9677219162451f359c93e58979c1ff8282d2228d Mon Sep 17 00:00:00 2001 From: harshit078 Date: Wed, 19 Mar 2025 18:10:15 +0530 Subject: [PATCH 3/8] Added tests for error handling in app.py --- .../tests/tests_error_handling.py | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 backend/analytics_server/tests/tests_error_handling.py diff --git a/backend/analytics_server/tests/tests_error_handling.py b/backend/analytics_server/tests/tests_error_handling.py new file mode 100644 index 00000000..2e067893 --- /dev/null +++ b/backend/analytics_server/tests/tests_error_handling.py @@ -0,0 +1,112 @@ +import unittest +import json +from werkzeug.exceptions import NotFound, BadRequest + +from flask import Flask, jsonify, request + +flask_app = Flask(__name__) + +@flask_app.errorhandler(Exception) +def handle_exception(e): + """Handle non-HTTP exceptions by returning JSON""" + error_details = { + "error": str(e) or "Internal Server Error", + "status_code": 500, + "path": request.path, + "exception_type": e.__class__.__name__, + } + if flask_app.debug: + import traceback + error_details["traceback"] = traceback.format_exc() + response = jsonify(error_details) + response.status_code = 500 + return response + +@flask_app.errorhandler(NotFound) +@flask_app.errorhandler(BadRequest) +def handle_http_exception(e): + """Handle HTTP exceptions by returning JSON""" + response = jsonify( + {"error": e.description, "status_code": e.code, "path": request.path} + ) + response.status_code = e.code + return response + +# Added test routes +@flask_app.route("/test-bad-request") +def bad_request_endpoint(): + raise BadRequest("Invalid input") + +@flask_app.route("/test-exception") +def exception_endpoint(): + raise ValueError("Something went wrong") + +@flask_app.route("/test-debug-exception") +def debug_exception_endpoint(): + raise ValueError("Debug exception") + +@flask_app.route("/test-prod-exception") +def prod_exception_endpoint(): + raise ValueError("Production exception") + +class TestErrorHandlers(unittest.TestCase): + + def setUp(self): + self.app = flask_app.test_client() + flask_app.config["TESTING"] = True + flask_app.config["DEBUG"] = False + + def test_http_exception_handler_404(self): + """Test handling of 404 Not Found exception""" + response = self.app.get("/non-existent-endpoint") + + self.assertEqual(response.status_code, 404) + data = json.loads(response.data) + self.assertIn("error", data) + self.assertEqual(data["status_code"], 404) + self.assertEqual(data["path"], "/non-existent-endpoint") + + def test_http_exception_handler_400(self): + """Test handling of 400 Bad Request exception""" + response = self.app.get("/test-bad-request") + + self.assertEqual(response.status_code, 400) + data = json.loads(response.data) + self.assertIn("error", data) + self.assertEqual(data["status_code"], 400) + self.assertEqual(data["path"], "/test-bad-request") + self.assertEqual(data["error"], "Invalid input") + + def test_general_exception_handler(self): + """Test handling of general exceptions""" + response = self.app.get("/test-exception") + + self.assertEqual(response.status_code, 500) + data = json.loads(response.data) + self.assertIn("error", data) + self.assertEqual(data["status_code"], 500) + self.assertEqual(data["path"], "/test-exception") + self.assertEqual(data["exception_type"], "ValueError") + self.assertEqual(data["error"], "Something went wrong") + + def test_debug_mode_traceback(self): + """Test that traceback is included in debug mode""" + flask_app.config["DEBUG"] = True + + response = self.app.get("/test-debug-exception") + + data = json.loads(response.data) + self.assertIn("traceback", data) + self.assertTrue(len(data["traceback"]) > 0) + + flask_app.config["DEBUG"] = False + + def test_no_traceback_in_production(self): + """Test that traceback is not included when not in debug mode""" + flask_app.config["DEBUG"] = False + response = self.app.get("/test-prod-exception") + data = json.loads(response.data) + self.assertNotIn("traceback", data) + +if __name__ == "__main__": + unittest.main() From 5fa6dfd0d511e3a47703a3446a7fa69eb61ecd22 Mon Sep 17 00:00:00 2001 From: harshit078 Date: Wed, 19 Mar 2025 18:11:03 +0530 Subject: [PATCH 4/8] Minor fix in spacing in tests --- backend/analytics_server/tests/tests_error_handling.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/backend/analytics_server/tests/tests_error_handling.py b/backend/analytics_server/tests/tests_error_handling.py index 2e067893..b55f41bc 100644 --- a/backend/analytics_server/tests/tests_error_handling.py +++ b/backend/analytics_server/tests/tests_error_handling.py @@ -6,6 +6,7 @@ flask_app = Flask(__name__) + @flask_app.errorhandler(Exception) def handle_exception(e): """Handle non-HTTP exceptions by returning JSON""" @@ -17,11 +18,13 @@ def handle_exception(e): } if flask_app.debug: import traceback + error_details["traceback"] = traceback.format_exc() response = jsonify(error_details) response.status_code = 500 return response + @flask_app.errorhandler(NotFound) @flask_app.errorhandler(BadRequest) def handle_http_exception(e): @@ -32,23 +35,28 @@ def handle_http_exception(e): response.status_code = e.code return response + # Added test routes @flask_app.route("/test-bad-request") def bad_request_endpoint(): raise BadRequest("Invalid input") + @flask_app.route("/test-exception") def exception_endpoint(): raise ValueError("Something went wrong") + @flask_app.route("/test-debug-exception") def debug_exception_endpoint(): raise ValueError("Debug exception") + @flask_app.route("/test-prod-exception") def prod_exception_endpoint(): raise ValueError("Production exception") + class TestErrorHandlers(unittest.TestCase): def setUp(self): @@ -108,5 +116,6 @@ def test_no_traceback_in_production(self): data = json.loads(response.data) self.assertNotIn("traceback", data) + if __name__ == "__main__": unittest.main() From 7a80165c0155e3a8766725d72e2236532415b6ac Mon Sep 17 00:00:00 2001 From: harshit078 Date: Wed, 9 Apr 2025 02:57:06 +0530 Subject: [PATCH 5/8] Resolved black Integration test failing --- backend/analytics_server/app.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/backend/analytics_server/app.py b/backend/analytics_server/app.py index 7be31d4d..a83190c4 100644 --- a/backend/analytics_server/app.py +++ b/backend/analytics_server/app.py @@ -38,18 +38,18 @@ configure_db_with_app(app) initialize_database(app) + # HTTP Error handler @app.errorhandler(HTTPException) def handle_http_exception(e): """Handle HTTP exceptions by returning JSON""" - response = jsonify({ - "error": e.description, - "status_code": e.code, - "path": request.path - }) + response = jsonify( + {"error": e.description, "status_code": e.code, "path": request.path} + ) response.status_code = e.code return response + # Error handler @app.errorhandler(Exception) def handle_exception(e): @@ -58,16 +58,17 @@ def handle_exception(e): "error": str(e) or "Internal Server Error", "status_code": 500, "path": request.path, - "exception_type": e.__class__.__name__ + "exception_type": e.__class__.__name__, } - + if app.debug: error_details["traceback"] = traceback.format_exc() - + response = jsonify(error_details) response.status_code = 500 return response + app.register_error_handler(Exception, handle_exception) app.register_error_handler(HTTPException, handle_http_exception) From 271b06c346222e2474e102e15136d6eeef2a9536 Mon Sep 17 00:00:00 2001 From: harshit078 Date: Wed, 16 Apr 2025 11:46:15 +0530 Subject: [PATCH 6/8] Added JSON error handling in sync_app instead of HTML error for improved error structure layout --- backend/analytics_server/sync_app.py | 35 +++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/backend/analytics_server/sync_app.py b/backend/analytics_server/sync_app.py index c6711757..40bac2ea 100644 --- a/backend/analytics_server/sync_app.py +++ b/backend/analytics_server/sync_app.py @@ -1,6 +1,8 @@ from os import getenv -from flask import Flask +from flask import Flask, jsonify, request +from werkzeug.exceptions import HTTPException +import traceback from env import load_app_env @@ -19,5 +21,36 @@ configure_db_with_app(app) +# HTTP Error handler +@app.errorhandler(HTTPException) +def handle_http_exception(e): + """Handle HTTP exceptions by returning JSON""" + response = jsonify( + {"error": e.description, "status_code": e.code, "path": request.path} + ) + response.status_code = e.code + return response + +# Error handling +@app.errorhandler(Exception) +def handle_exception(e): + """Handle non-HTTP exceptions by returning JSON""" + error_details = { + "error": str(e) or "Internal Server Error", + "status_code": 500, + "path": request.path, + "exception_type": e.__class__.__name__, + } + + if app.debug: + error_details["traceback"] = traceback.format_exc() + + response = jsonify(error_details) + response.status_code = 500 + return response + +app.register_error_handler(Exception, handle_exception) +app.register_error_handler(HTTPException, handle_http_exception) + if __name__ == "__main__": app.run(port=SYNC_SERVER_PORT) From 43a21c2f98139ac77f28f23f741621f5b0cb18e8 Mon Sep 17 00:00:00 2001 From: harshit078 Date: Thu, 17 Apr 2025 23:33:25 +0530 Subject: [PATCH 7/8] Removed error handlers and improved code --- backend/analytics_server/sync_app.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/backend/analytics_server/sync_app.py b/backend/analytics_server/sync_app.py index 40bac2ea..da349642 100644 --- a/backend/analytics_server/sync_app.py +++ b/backend/analytics_server/sync_app.py @@ -45,12 +45,7 @@ def handle_exception(e): if app.debug: error_details["traceback"] = traceback.format_exc() - response = jsonify(error_details) - response.status_code = 500 - return response - -app.register_error_handler(Exception, handle_exception) -app.register_error_handler(HTTPException, handle_http_exception) + return jsonify(error_details), 500 if __name__ == "__main__": app.run(port=SYNC_SERVER_PORT) From 20378404f90bcd212970bc4d29a4a415e62d2100 Mon Sep 17 00:00:00 2001 From: harshit078 Date: Thu, 24 Apr 2025 02:38:19 +0530 Subject: [PATCH 8/8] Removed redundant error handler in app.py --- backend/analytics_server/app.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/backend/analytics_server/app.py b/backend/analytics_server/app.py index a83190c4..35c78b4b 100644 --- a/backend/analytics_server/app.py +++ b/backend/analytics_server/app.py @@ -69,8 +69,5 @@ def handle_exception(e): return response -app.register_error_handler(Exception, handle_exception) -app.register_error_handler(HTTPException, handle_http_exception) - if __name__ == "__main__": app.run(port=int(ANALYTICS_SERVER_PORT))