Exception handling for database queries

This commit is contained in:
2022-08-20 10:56:43 +01:00
parent b8fd65d856
commit 866c9b10cf
15 changed files with 234 additions and 114 deletions

View File

@ -2,8 +2,8 @@ from ..extensions import db
from ..tools.encryption import decrypt, encrypt
from ..tools.logs import write
from flask import flash
from flask import current_app as app
from flask.helpers import flash
from flask_login import current_user
from sqlalchemy.exc import SQLAlchemyError
from werkzeug.utils import secure_filename
@ -43,11 +43,13 @@ class Dataset(db.Model):
def get_name(self): return decrypt(self.name)
def make_default(self):
for dataset in Dataset.query.all():
dataset.default = False
self.default = True
try:
db.session.commit()
for dataset in Dataset.query.all(): dataset.default = False
except SQLAlchemyError as exception:
write('system.log', f'Database error when setting default dataset {self.id}: {exception}')
return False, f'Database error {exception}.'
self.default = True
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when setting default dataset {self.id}: {exception}')
@ -61,10 +63,14 @@ class Dataset(db.Model):
message = 'Cannot delete the default dataset.'
flash(message, 'error')
return False, message
if Dataset.query.count() == 1:
message = 'Cannot delete the only dataset.'
flash(message, 'error')
return False, message
try:
if Dataset.query.count() == 1:
message = 'Cannot delete the only dataset.'
flash(message, 'error')
return False, message
except SQLAlchemyError as exception:
write('system.log', f'Database error when setting default dataset {self.id}: {exception}')
return False, f'Database error {exception}.'
write('system.log', f'Dataset {self.id} deleted by {current_user.get_username()}.')
filename = secure_filename('.'.join([self.id,'json']))
data = Path(app.config.get('DATA'))

View File

@ -84,8 +84,7 @@ class Entry(db.Model):
def start(self):
self.start_time = datetime.now()
self.status = 'started'
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when starting test for {self.get_surname()}, {self.get_first_name()}: {exception}')
@ -104,8 +103,7 @@ class Entry(db.Model):
else:
self.status = 'late'
self.valid = False
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when submitting entry for {self.get_surname()}, {self.get_first_name()}: {exception}')
@ -118,8 +116,7 @@ class Entry(db.Model):
if self.status == 'started': return False, 'The entry is still pending.'
self.valid = True
self.status = 'completed'
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when validating entry {self.id}: {exception}')
@ -201,7 +198,6 @@ class Entry(db.Model):
<p>Best wishes, <br/> SKA Refereeing</p>
"""
)
try:
mail.send(email)
try: mail.send(email)
except SMTPException as exception:
write('system.log', f'SMTP Error when trying to notify results to {self.get_surname()}, {self.get_first_name()} with error: {exception}')

View File

@ -66,8 +66,7 @@ class Test(db.Model):
def delete(self):
if self.entries: return False, f'Cannot delete a test with submitted entries.'
db.session.delete(self)
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when deleting test {self.get_code()}: {exception}')
@ -79,8 +78,7 @@ class Test(db.Model):
now = datetime.now()
if self.start_date.date() > now.date():
self.start_date = now
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when launching test {self.get_code()}: {exception}')
@ -93,8 +91,7 @@ class Test(db.Model):
now = datetime.now()
if self.end_date >= now:
self.end_date = now
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when closing test {self.get_code()}: {exception}')
@ -108,8 +105,7 @@ class Test(db.Model):
code = secrets.token_hex(3).lower()
adjustments[code] = time
self.adjustments = adjustments
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when adding adjustment to test {self.get_code()}: {exception}')
@ -121,8 +117,7 @@ class Test(db.Model):
if not self.adjustments: return False, f'There are no adjustments configured for test {self.get_code()}.'
self.adjustments.pop(code)
if not self.adjustments: self.adjustments = None
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when deleting adjustment from test {self.get_code()}: {exception}')
@ -135,8 +130,7 @@ class Test(db.Model):
if start_date: self.start_date = start_date
if end_date: self.end_date = end_date
if time_limit is not None: self.time_limit = time_limit
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when updating test {self.get_code()}: {exception}')

View File

@ -2,8 +2,8 @@ from ..extensions import db, mail
from ..tools.encryption import decrypt, encrypt
from ..tools.logs import write
from flask import flash, jsonify, session
from flask.helpers import url_for
from flask import jsonify, session
from flask.helpers import flash, url_for
from flask_login import current_user, login_user, logout_user, UserMixin
from flask_mail import Message
from smtplib import SMTPException
@ -57,7 +57,10 @@ class User(UserMixin, db.Model):
def register(self, notify:bool=False, password:str=None):
self.generate_id()
users = User.query.all()
try: users = User.query.all()
except SQLAlchemyError as exception:
write('system.log', f'Database error when setting default dataset {self.id}: {exception}')
return False, f'Database error {exception}.'
for user in users:
if user.get_username() == self.get_username(): return False, f'Username {self.get_username()} already in use.'
if user.get_email() == self.get_email(): return False, f'Email address {self.get_email()} already in use.'
@ -97,8 +100,7 @@ class User(UserMixin, db.Model):
<p>SKA Refereeing</p>
"""
)
try:
mail.send(email)
try: mail.send(email)
except SMTPException as exception:
write('system.log', f'SMTP Error while trying to notify new user account creation to {self.get_username()} with error: {exception}')
return True, f'User {self.get_username()} was created successfully.'
@ -151,14 +153,12 @@ class User(UserMixin, db.Model):
<p>SKA Refereeing</p>
"""
)
try:
mail.send(email)
try: mail.send(email)
except SMTPException as exception:
write('system.log', f'SMTP Error while trying to reset password for {self.get_username()} with error: {exception}')
db.session.rollback()
return jsonify({'error': f'SMTP Error: {exception}'}), 500
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when resetting password for user {self.get_username()}: {exception}')
@ -167,8 +167,7 @@ class User(UserMixin, db.Model):
def clear_reset_tokens(self):
self.reset_token = self.verification_token = None
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when resetting clearing reset tokens for user {self.get_username()}: {exception}')
@ -208,8 +207,7 @@ class User(UserMixin, db.Model):
<p>SKA Refereeing</p>
"""
)
try:
mail.send(email)
try: mail.send(email)
except SMTPException as exception:
write('system.log', f'SMTP Error when trying to delete account {username} with error: {exception}')
return True, message
@ -219,11 +217,14 @@ class User(UserMixin, db.Model):
if password: self.set_password(password)
old_email = self.get_email()
if email:
for entry in User.query.all():
if entry.get_email() == email and not entry == self: return False, f'The email address {email} is already in use.'
try:
for entry in User.query.all():
if entry.get_email() == email and not entry == self: return False, f'The email address {email} is already in use.'
except SQLAlchemyError as exception:
write('system.log', f'Database error when setting default dataset {self.id}: {exception}')
return False, f'Database error {exception}.'
self.set_email(email)
try:
db.session.commit()
try: db.session.commit()
except SQLAlchemyError as exception:
db.session.rollback()
write('system.log', f'Database error when updating user {self.get_username()}: {exception}')
@ -257,8 +258,7 @@ class User(UserMixin, db.Model):
<p>SKA Refereeing</p>
"""
)
try:
mail.send(message)
try: mail.send(message)
except SMTPException as exception:
write('system.log', f'SMTP Error when trying to update account {self.get_username()} with error: {exception}')
return True, f'Account {self.get_username()} has been updated.'