Files
TimeTracker/app/utils/db.py
Dries Peeters 8a378b7078 feat(clients,license,db): add client management, enhanced DB init, and tests
- Clients: add model, routes, and templates
  - app/models/client.py
  - app/routes/clients.py
  - templates/clients/{create,edit,list,view}.html
  - docs/CLIENT_MANAGEMENT_README.md
- Database: add enhanced init/verify scripts, migrations, and docs
  - docker/{init-database-enhanced.py,start-enhanced.py,verify-database.py}
  - docs/ENHANCED_DATABASE_STARTUP.md
  - migrations/{add_analytics_column.sql,add_analytics_setting.py,migrate_to_client_model.py}
- Scripts: add version manager and docker network test helpers
  - scripts/version-manager.{bat,ps1,py,sh}
  - scripts/test-docker-network.{bat,sh}
  - docs/VERSION_MANAGEMENT.md
- UI: tweak base stylesheet
  - app/static/base.css
- Tests: add client system test
  - test_client_system.py
2025-09-01 11:34:45 +02:00

54 lines
1.6 KiB
Python

from typing import Optional, Dict, Any
from flask import current_app
from sqlalchemy.exc import SQLAlchemyError
from app import db
def safe_commit(action: Optional[str] = None, context: Optional[Dict[str, Any]] = None) -> bool:
"""Commit the current database session with robust error handling.
- Rolls back the session on failure
- Logs the exception with context
- Returns True on success, False on failure
"""
try:
db.session.commit()
return True
except SQLAlchemyError as e:
try:
db.session.rollback()
finally:
pass
try:
if action:
if context:
current_app.logger.exception(
"Database commit failed during %s | context=%s | error=%s",
action,
context,
e,
)
else:
current_app.logger.exception(
"Database commit failed during %s | error=%s", action, e
)
else:
current_app.logger.exception("Database commit failed: %s", e)
except Exception:
# As a last resort, avoid crashing the request due to logging errors
pass
return False
except Exception as e:
# Catch-all for unexpected errors
try:
db.session.rollback()
finally:
pass
try:
current_app.logger.exception("Unexpected database error on commit: %s", e)
except Exception:
pass
return False