improve database error handling, implement automatic reconnects, raise specialized errors
This commit is contained in:
parent
ec2b5f0b0d
commit
ac805e96da
@ -1,5 +1,6 @@
|
||||
import logging
|
||||
import sys
|
||||
from time import sleep
|
||||
|
||||
from datetime import date, datetime
|
||||
from typing import Optional
|
||||
|
||||
@ -25,23 +26,33 @@ class NoDatabaseConnectionError(Exception):
|
||||
pass
|
||||
|
||||
class DatabaseService:
|
||||
MAX_CONNECTION_RETRIES = 5
|
||||
def __init__(self, database_config: DatabaseConfiguration) -> None:
|
||||
self._database_config = database_config
|
||||
try:
|
||||
logger.info(
|
||||
f"Connecting to database '{self._database_config.db_name}' on "
|
||||
f"{self._database_config.db_user}@{self._database_config.db_host}:{self._database_config.db_port}"
|
||||
)
|
||||
self._connection = mariadb.connect(
|
||||
user=self._database_config.db_user,
|
||||
password=self._database_config.db_password,
|
||||
host=self._database_config.db_host,
|
||||
port=self._database_config.db_port,
|
||||
database=self._database_config.db_name
|
||||
)
|
||||
except mariadb.Error as e:
|
||||
logger.error(f"Error connecting to database: {e}")
|
||||
raise NoDatabaseConnectionError
|
||||
logger.info(
|
||||
f"Connecting to database '{self._database_config.db_name}' on "
|
||||
f"{self._database_config.db_user}@{self._database_config.db_host}:{self._database_config.db_port}"
|
||||
)
|
||||
self._establish_new_connection()
|
||||
|
||||
def _establish_new_connection(self) -> None:
|
||||
retries = 0
|
||||
for _ in range(DatabaseService.MAX_CONNECTION_RETRIES):
|
||||
try:
|
||||
self._connection = mariadb.connect(
|
||||
user=self._database_config.db_user,
|
||||
password=self._database_config.db_password,
|
||||
host=self._database_config.db_host,
|
||||
port=self._database_config.db_port,
|
||||
database=self._database_config.db_name
|
||||
)
|
||||
except mariadb.Error:
|
||||
sleep(0.5)
|
||||
retries += 1
|
||||
continue
|
||||
return
|
||||
raise NoDatabaseConnectionError
|
||||
|
||||
|
||||
def _get_cursor(self) -> Cursor:
|
||||
return self._connection.cursor()
|
||||
@ -98,6 +109,9 @@ class DatabaseService:
|
||||
"VALUES (?, ?, ?)", (user_name, user_mail.lower(), password_hash)
|
||||
)
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.create_user(user_name, user_mail, password_hash)
|
||||
except mariadb.IntegrityError as e:
|
||||
logger.warning(f"Aborted duplication entry: {e}")
|
||||
raise DuplicationError
|
||||
@ -115,6 +129,9 @@ class DatabaseService:
|
||||
user.user_id)
|
||||
)
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.update_user(user)
|
||||
except mariadb.IntegrityError as e:
|
||||
logger.warning(f"Aborted duplication entry: {e}")
|
||||
raise DuplicationError
|
||||
@ -129,6 +146,9 @@ class DatabaseService:
|
||||
(transaction.user_id, transaction.value, transaction.is_debit, transaction.transaction_date, transaction.reference)
|
||||
)
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.add_transaction(transaction)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error adding Transaction: {e}")
|
||||
return
|
||||
@ -143,6 +163,9 @@ class DatabaseService:
|
||||
cursor.execute("SELECT * FROM transactions WHERE user_id=?", (user_id,))
|
||||
self._connection.commit()
|
||||
result = cursor.fetchall()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.get_all_transactions_for_user(user_id)
|
||||
except mariadb.Error as e:
|
||||
logger.error(f"Error getting all transactions for user: {e}")
|
||||
return []
|
||||
@ -166,6 +189,9 @@ class DatabaseService:
|
||||
(news.content, news.title, news.subtitle, news.author.user_id, news.news_date)
|
||||
)
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.add_news(news)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error adding Transaction: {e}")
|
||||
|
||||
@ -175,6 +201,9 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute("SELECT * FROM news INNER JOIN users ON news.news_author = users.user_id WHERE news_date BETWEEN ? AND ?;", (dt_start, dt_end))
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.get_news(dt_start, dt_end)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error fetching news: {e}")
|
||||
return []
|
||||
@ -198,6 +227,9 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute("SELECT * FROM tickets INNER JOIN users ON tickets.user = users.user_id;", ())
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.get_tickets()
|
||||
except Exception as e:
|
||||
logger.warning(f"Error fetching tickets: {e}")
|
||||
return []
|
||||
@ -218,6 +250,9 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute("SELECT * FROM tickets INNER JOIN users ON tickets.user = users.user_id WHERE user_id=?;", (user_id, ))
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.get_ticket_for_user(user_id)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error fetching ticket for user: {e}")
|
||||
return
|
||||
@ -239,6 +274,9 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute("INSERT INTO tickets (ticket_category, user) VALUES (?, ?)", (category, user_id))
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.generate_ticket_for_user(user_id, category)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error generating ticket for user: {e}")
|
||||
return
|
||||
@ -251,6 +289,9 @@ class DatabaseService:
|
||||
cursor.execute("UPDATE tickets SET user = ? WHERE ticket_id = ?;", (new_owner_id, ticket_id))
|
||||
affected_rows = cursor.rowcount
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.change_ticket_owner(ticket_id, new_owner_id)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error transferring ticket to user: {e}")
|
||||
return False
|
||||
@ -261,6 +302,9 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute("DELETE FROM tickets WHERE ticket_id = ?;", (ticket_id, ))
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.change_ticket_owner(ticket_id)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error deleting ticket: {e}")
|
||||
return False
|
||||
@ -274,6 +318,9 @@ class DatabaseService:
|
||||
for seat in seats:
|
||||
cursor.execute("INSERT INTO seats (seat_id, seat_category) VALUES (?, ?);", (seat[0], seat[1]))
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.generate_fresh_seats_table(seats)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error generating fresh seats table: {e}")
|
||||
return
|
||||
@ -284,6 +331,9 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute("SELECT seats.*, users.* FROM seats LEFT JOIN users ON seats.user = users.user_id;")
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.get_seating_info()
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting seats table: {e}")
|
||||
return results
|
||||
@ -304,6 +354,9 @@ class DatabaseService:
|
||||
cursor.execute("UPDATE seats SET user = ? WHERE seat_id = ?;", (user_id, seat_id))
|
||||
affected_rows = cursor.rowcount
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.seat_user(seat_id, user_id)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error seating user: {e}")
|
||||
return False
|
||||
@ -315,6 +368,9 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute("SELECT * FROM catering_menu_items;")
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.get_menu_items()
|
||||
except Exception as e:
|
||||
logger.warning(f"Error fetching menu items: {e}")
|
||||
return results
|
||||
@ -336,6 +392,9 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute("SELECT * FROM catering_menu_items WHERE catering_menu_item_id = ?;", (menu_item_id, ))
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.get_menu_item(menu_item_id)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error fetching menu items: {e}")
|
||||
return
|
||||
@ -360,6 +419,9 @@ class DatabaseService:
|
||||
(name, info, price, category.value, is_disabled)
|
||||
)
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.add_menu_item(name, info, price, category, is_disabled)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error adding menu item: {e}")
|
||||
return
|
||||
@ -378,6 +440,9 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute("DELETE FROM catering_menu_items WHERE catering_menu_item_id = ?;", (menu_item_id,))
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.delete_menu_item(menu_item_id)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error deleting menu item: {e}")
|
||||
return False
|
||||
@ -392,6 +457,9 @@ class DatabaseService:
|
||||
)
|
||||
affected_rows = cursor.rowcount
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.update_menu_item(updated_item)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error updating menu item: {e}")
|
||||
return False
|
||||
@ -420,6 +488,9 @@ class DatabaseService:
|
||||
customer=self.get_user_by_id(user_id),
|
||||
is_delivery=is_delivery
|
||||
)
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.add_new_order(menu_items, user_id, is_delivery)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error placing order: {e}")
|
||||
return
|
||||
@ -433,6 +504,9 @@ class DatabaseService:
|
||||
)
|
||||
affected_rows = cursor.rowcount
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.change_order_status(order_id, status)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error updating menu item: {e}")
|
||||
return False
|
||||
@ -453,6 +527,9 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute(query)
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.get_orders(user_id, status)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting orders: {e}")
|
||||
return fetched_orders
|
||||
@ -482,6 +559,9 @@ class DatabaseService:
|
||||
(order_id, )
|
||||
)
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.get_menu_items_for_order(order_id)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting order items: {e}")
|
||||
return result
|
||||
@ -506,6 +586,9 @@ class DatabaseService:
|
||||
(user_id, picture_data)
|
||||
)
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.set_user_profile_picture(user_id, picture_data)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error setting user profile picture: {e}")
|
||||
|
||||
@ -518,6 +601,9 @@ class DatabaseService:
|
||||
if r is None:
|
||||
return
|
||||
return r[0]
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.get_user_profile_picture(user_id)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error setting user profile picture: {e}")
|
||||
return None
|
||||
@ -528,6 +614,9 @@ class DatabaseService:
|
||||
try:
|
||||
cursor.execute("SELECT * FROM users;")
|
||||
self._connection.commit()
|
||||
except mariadb.InterfaceError:
|
||||
self._establish_new_connection()
|
||||
return self.get_all_users()
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting all users: {e}")
|
||||
return results
|
||||
|
||||
Loading…
Reference in New Issue
Block a user