fix: add database error handling throughout app

Wrap all sqlite3 operations in try/except sqlite3.Error:
- SELECT on validation error path: falls back to empty guest list
- INSERT on form submit: shows user-friendly retry message
- SELECT on page load: falls back to empty guest list
- SELECT in /api/guests: returns 503 JSON response
This commit is contained in:
2026-03-09 20:24:09 -06:00
parent a178e6193b
commit 920463b4a7
+49 -32
View File
@@ -96,33 +96,46 @@ def index():
logger.warning("Profanity detected in comment.") logger.warning("Profanity detected in comment.")
if error: if error:
conn = sqlite3.connect(DATABASE) try:
c = conn.cursor() conn = sqlite3.connect(DATABASE)
# TODO: No error handling — a locked/corrupted DB returns an unhandled 500. Wrap in try/except. c = conn.cursor()
c.execute('SELECT first_name, location FROM guests ORDER BY id DESC LIMIT 100') c.execute('SELECT first_name, location FROM guests ORDER BY id DESC LIMIT 100')
guests = c.fetchall() guests = c.fetchall()
conn.close() conn.close()
except sqlite3.Error as e:
logger.error("Database error loading guests: %s", e)
guests = []
return render_template('index.html', error=error, guests=guests) return render_template('index.html', error=error, guests=guests)
conn = sqlite3.connect(DATABASE) try:
c = conn.cursor() conn = sqlite3.connect(DATABASE)
c.execute( c = conn.cursor()
''' c.execute(
INSERT INTO guests (first_name, last_name, email, location, comment, newsletter_opt_in) '''
VALUES (?, ?, ?, ?, ?, ?) INSERT INTO guests (first_name, last_name, email, location, comment, newsletter_opt_in)
''', VALUES (?, ?, ?, ?, ?, ?)
(first_name, last_name, email, location, comment, newsletter_opt_in) ''',
) (first_name, last_name, email, location, comment, newsletter_opt_in)
conn.commit() )
conn.close() conn.commit()
conn.close()
except sqlite3.Error as e:
logger.error("Database error saving guest: %s", e)
return render_template('index.html',
error="Unable to save your entry. Please try again.",
guests=[])
logger.info("Added guest: %s %s from %s", first_name, last_name, location) logger.info("Added guest: %s %s from %s", first_name, last_name, location)
return redirect(url_for('index')) return redirect(url_for('index'))
conn = sqlite3.connect(DATABASE) try:
c = conn.cursor() conn = sqlite3.connect(DATABASE)
c.execute('SELECT first_name, location FROM guests ORDER BY id DESC LIMIT 100') c = conn.cursor()
guests = c.fetchall() c.execute('SELECT first_name, location FROM guests ORDER BY id DESC LIMIT 100')
conn.close() guests = c.fetchall()
conn.close()
except sqlite3.Error as e:
logger.error("Database error loading guests: %s", e)
guests = []
logger.info("Rendering index with %d guests.", len(guests)) logger.info("Rendering index with %d guests.", len(guests))
return render_template('index.html', error=error, guests=guests) return render_template('index.html', error=error, guests=guests)
@@ -132,16 +145,20 @@ def api_guests():
if api_key != os.environ.get("API_KEY"): if api_key != os.environ.get("API_KEY"):
abort(403) abort(403)
conn = sqlite3.connect(DATABASE) try:
c = conn.cursor() conn = sqlite3.connect(DATABASE)
c.execute(''' c = conn.cursor()
SELECT first_name, last_name, email, location, comment, newsletter_opt_in, timestamp c.execute('''
FROM guests SELECT first_name, last_name, email, location, comment, newsletter_opt_in, timestamp
WHERE email IS NOT NULL AND email != '' FROM guests
ORDER BY id DESC WHERE email IS NOT NULL AND email != ''
''') ORDER BY id DESC
rows = c.fetchall() ''')
conn.close() rows = c.fetchall()
conn.close()
except sqlite3.Error as e:
logger.error("Database error in api_guests: %s", e)
return jsonify({"error": "Database unavailable"}), 503
guests = [ guests = [
{ {