feat: add logging and SMTP error handling
Logging: - Add structured logging with timestamps - Log successful and failed login attempts - Log new orders and order completions - Log email sending success/failures SMTP Error Handling: - Add try/except block around SMTP operations - Catch authentication errors, SMTP exceptions, and general errors - Log all email failures with detailed error messages - Ensure orders are saved even if email fails This allows monitoring of critical operations and troubleshooting email delivery issues through systemd journal. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
22
wawi/app.py
22
wawi/app.py
@@ -14,6 +14,7 @@ import secrets
|
||||
import smtplib
|
||||
import time
|
||||
import threading
|
||||
import logging
|
||||
from uuid import uuid4
|
||||
from email.message import EmailMessage
|
||||
from functools import wraps
|
||||
@@ -31,6 +32,14 @@ DB_PATH = BASE_DIR / "hellas.db"
|
||||
UPLOAD_DIR = BASE_DIR / "static" / "uploads"
|
||||
ALLOWED_EXT = {".png", ".jpg", ".jpeg", ".webp", ".gif"}
|
||||
|
||||
# Logging konfigurieren
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s [%(levelname)s] %(name)s: %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Optionaler Prefix (z. B. /wawi), wenn die App hinter einem Sub‑Pfad läuft.
|
||||
URL_PREFIX = os.environ.get("URL_PREFIX", "").strip().rstrip("/")
|
||||
STATIC_URL_PATH = f"{URL_PREFIX}/static" if URL_PREFIX else "/static"
|
||||
@@ -490,8 +499,10 @@ def login():
|
||||
).fetchone()
|
||||
if row and check_password_hash(row["password_hash"], password):
|
||||
session["user"] = user
|
||||
logger.info(f"Erfolgreicher Login: {user}")
|
||||
nxt = request.args.get("next") or url_for("bp.index")
|
||||
return redirect(nxt)
|
||||
logger.warning(f"Fehlgeschlagener Login-Versuch: {user}")
|
||||
return render_template("login.html", error=True)
|
||||
return render_template("login.html", error=False)
|
||||
|
||||
@@ -653,6 +664,7 @@ def order():
|
||||
),
|
||||
)
|
||||
db.commit()
|
||||
logger.info(f"Neue Bestellung: {data.get('artikel')} ({data.get('groesse')}) x{data.get('menge')} von {data.get('name')}")
|
||||
|
||||
to_addr = os.environ.get("ORDER_TO", "bjoern@welker.me")
|
||||
smtp_host = os.environ.get("SMTP_HOST")
|
||||
@@ -683,10 +695,19 @@ def order():
|
||||
msg.set_content(body)
|
||||
|
||||
def _send():
|
||||
"""Sendet Bestellungs-Email asynchron mit Error Handling."""
|
||||
try:
|
||||
with smtplib.SMTP(smtp_host, smtp_port) as server:
|
||||
server.starttls()
|
||||
server.login(smtp_user, smtp_pass)
|
||||
server.send_message(msg, to_addrs=recipients)
|
||||
logger.info(f"Bestellungs-Email erfolgreich versendet an {', '.join(recipients)}")
|
||||
except smtplib.SMTPAuthenticationError as e:
|
||||
logger.error(f"SMTP-Authentifizierung fehlgeschlagen: {e}")
|
||||
except smtplib.SMTPException as e:
|
||||
logger.error(f"SMTP-Fehler beim Email-Versand: {e}")
|
||||
except Exception as e:
|
||||
logger.error(f"Unerwarteter Fehler beim Email-Versand: {e}", exc_info=True)
|
||||
|
||||
threading.Thread(target=_send, daemon=True).start()
|
||||
|
||||
@@ -758,6 +779,7 @@ def complete_order(order_id: int):
|
||||
(user, now_iso(), order_id),
|
||||
)
|
||||
db.commit()
|
||||
logger.info(f"Bestellung #{order_id} abgeschlossen von {user}")
|
||||
return redirect(url_for("bp.orders"))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user