From 09baf6d1e85573feca8d23191ec2169b4c3a6a36 Mon Sep 17 00:00:00 2001 From: Vadim Troshchinskiy Date: Thu, 6 Feb 2025 09:38:31 +0100 Subject: [PATCH] Fix HTTP exception handling Using too general of an exception was causing problems. --- api/gitapi.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/api/gitapi.py b/api/gitapi.py index f55dce9..91cc7f0 100755 --- a/api/gitapi.py +++ b/api/gitapi.py @@ -60,6 +60,9 @@ from flask_restx import Api, Resource, fields #from flasgger import Swagger import paramiko import logging +import traceback +from werkzeug.exceptions import HTTPException + from systemd.journal import JournalHandler debug_enabled = False @@ -168,13 +171,16 @@ def do_repo_gc(repo): return True -@app.errorhandler(Exception) +@app.errorhandler(HTTPException) def handle_exception(e): - """Return JSON for errors""" + """Return JSON for HTTP errors. + + We create and log an error UUID for each error, and use journald's additional fields for easier searching. + """ # start with the correct headers and status code from the error response = e.get_response() - errid = uuid.uuid4() + errid = uuid.uuid4().hex if debug_enabled: @@ -433,15 +439,21 @@ class GitTaskStatus(Resource): future = tasks[task_id] - if future.done(): - result = future.result() - log.info("Returning completion of task %s", task_id, extra = {"task_id" : task_id}) - return {"status" : "completed", "result" : result}, 200 - else: - log.info("Task %s is still in progress", task_id, extra = {"task_id" : task_id}) - return {"status" : "in progress"}, 202 + try: + if future.done(): + result = future.result() + log.info("Returning completion of task %s", task_id, extra = {"task_id" : task_id}) + return {"status" : "completed", "result" : result}, 200 + else: + log.info("Task %s is still in progress", task_id, extra = {"task_id" : task_id}) + return {"status" : "in progress"}, 202 + except Exception as e: + errid = uuid.uuid4().hex + log.error("Task %s failed with exception %s, UUID %s", task_id, traceback.format_exception(e), errid, extra = {"task_id" : task_id, "exception" : traceback.format_exception(e), "error_id" : errid}) + return {"status" : "internal error", "error_id" : errid }, 500 + @git_ns.route('/repositories/', methods=['DELETE']) class GitRepo(Resource):