From 49ef256986069a279c1be5068da9782ceff3b05f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20K=C3=BCnzel?= <simonk@fsmpi.rwth-aachen.de>
Date: Sun, 2 Jun 2024 20:19:27 +0200
Subject: [PATCH] Add site_is_overloaded error code

---
 api_specification.md              | 7 ++++++-
 src/api/miscellaneous/__init__.py | 3 ++-
 src/api/miscellaneous/errors.py   | 5 ++++-
 src/api/routes/route.py           | 7 ++++++-
 4 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/api_specification.md b/api_specification.md
index 07f2b9d..1d98282 100644
--- a/api_specification.md
+++ b/api_specification.md
@@ -1,4 +1,4 @@
-# Specification of the Web API for the Video-AG Website (v0.51).
+# Specification of the Web API for the Video-AG Website (v0.52).
 
 ## Introduction
 
@@ -1518,9 +1518,14 @@ Possible `error_code`:
 | too_many_suggestions                  | 403       |                                                      |
 | site_is_readonly                      | 503       |                                                      |
 | site_is_disabled                      | 503       |                                                      |
+| site_is_overloaded                    | 503       |                                                      |
 
 ## Changelog
 
+### v0.52
+
+* Added error code `site_is_overloaded`
+
 ### v0.51
 
 * Added `server_name` to `GET /status`
diff --git a/src/api/miscellaneous/__init__.py b/src/api/miscellaneous/__init__.py
index 7374751..ed3dc29 100644
--- a/src/api/miscellaneous/__init__.py
+++ b/src/api/miscellaneous/__init__.py
@@ -25,7 +25,8 @@ from api.miscellaneous.errors import (ApiError, ApiClientException, api_on_error
                                       ERROR_MODIFICATION_UNEXPECTED_CURRENT_VALUE,
                                       ERROR_TOO_MANY_SUGGESTIONS,
                                       ERROR_SITE_IS_READONLY,
-                                      ERROR_SITE_IS_DISABLED)
+                                      ERROR_SITE_IS_DISABLED,
+                                      ERROR_SITE_IS_OVERLOADED)
 from api.miscellaneous.rate_limiter import IntervalRateLimiter, HostBasedCounterRateLimiter, create_configured_host_rate_limiters
 from api.miscellaneous.diagnostics import DIAGNOSTICS_TRACKER, DiagnosticsCounter, DiagnosticsDataProvider
 from api.miscellaneous.scheduler import scheduled_function
diff --git a/src/api/miscellaneous/errors.py b/src/api/miscellaneous/errors.py
index f88be8c..d9e9556 100644
--- a/src/api/miscellaneous/errors.py
+++ b/src/api/miscellaneous/errors.py
@@ -83,6 +83,8 @@ ERROR_SITE_IS_READONLY = ApiError("site_is_readonly", HTTP_503_SERVICE_UNAVAILAB
                                   "The site is currently in read-only mode")
 ERROR_SITE_IS_DISABLED = ApiError("site_is_disabled", HTTP_503_SERVICE_UNAVAILABLE,
                                   "The site is currently disabled")
+ERROR_SITE_IS_OVERLOADED = ApiError("site_is_overloaded", HTTP_503_SERVICE_UNAVAILABLE,
+                                    "Your request failed, as the site is currently experiencing a lot of traffic")
 
 ALL_ERRORS_RANDOM = [
     ERROR_BAD_REQUEST(),
@@ -103,5 +105,6 @@ ALL_ERRORS_RANDOM = [
     ERROR_OBJECT_ERROR("?"),
     ERROR_TOO_MANY_SUGGESTIONS,
     ERROR_SITE_IS_READONLY,
-    ERROR_SITE_IS_DISABLED
+    ERROR_SITE_IS_DISABLED,
+    ERROR_SITE_IS_OVERLOADED
 ]
diff --git a/src/api/routes/route.py b/src/api/routes/route.py
index 122ebac..b9df183 100644
--- a/src/api/routes/route.py
+++ b/src/api/routes/route.py
@@ -5,6 +5,7 @@ from re import Pattern
 
 import api
 from api.authentication import is_moderator
+from api.database.database import TransactionConflictError, NoAvailableConnectionError
 from api.miscellaneous import *
 from api.version import get_api_path, API_LATEST_VERSION, API_OLDEST_ACTIVE_VERSION
 
@@ -189,8 +190,12 @@ def api_function(track_in_diagnostics: bool = True,
                     raise Exception(f"Api route {truncate_string(request.path)} returned result of unknown type: {str(result)}")
             except ApiClientException as e:
                 return api_on_error(e.error)
+            except (TransactionConflictError, NoAvailableConnectionError) as e:
+                print(f"An transaction conflict occurred while handling api request '{truncate_string(request.path, 200)}':")
+                traceback.print_exception(e)
+                return api_on_error(ERROR_SITE_IS_OVERLOADED)
             except Exception as e:
-                print("An exception occurred while handling api request:")
+                print(f"An exception occurred while handling api request '{truncate_string(request.path, 200)}':")
                 traceback.print_exception(e)
                 return api_on_error(ERROR_INTERNAL_SERVER_ERROR)
         
-- 
GitLab