1from akron.exceptions import AkronError
2from pydantic import ValidationError
3import logging
4
5# Setup logging
6logging.basicConfig(level=logging.INFO)
7logger = logging.getLogger(__name__)
8
9def safe_database_operation(db, operation_func, *args, **kwargs):
10 """Wrapper for safe database operations"""
11 try:
12 return operation_func(*args, **kwargs)
13 except ValidationError as e:
14 logger.error(f"Validation error: {e}")
15 return {"error": "Invalid data", "details": str(e)}
16 except AkronError as e:
17 logger.error(f"Database error: {e}")
18 return {"error": "Database operation failed", "details": str(e)}
19 except Exception as e:
20 logger.error(f"Unexpected error: {e}")
21 return {"error": "Operation failed", "details": str(e)}
22
23# Connection error handling
24def get_database_safely(db_url):
25 """Get database connection with error handling"""
26 try:
27 db = Akron(db_url)
28 # Test connection
29 if db.driver_type == "sqlite":
30 db.execute_raw("SELECT 1")
31 elif db.driver_type in ["mysql", "postgres"]:
32 db.execute_raw("SELECT 1")
33 elif db.driver_type == "mongodb":
34 db.execute_raw("db.runCommand({ping: 1})")
35
36 logger.info(f"Connected to {db.driver_type} database")
37 return db
38 except Exception as e:
39 logger.error(f"Failed to connect to database: {e}")
40 return None
41
42# CRUD with error handling
43def create_user_safely(db, user_data):
44 """Create user with comprehensive error handling"""
45 try:
46 # Validate data first
47 user = User(**user_data)
48
49 # Check if user already exists
50 existing = User.find(db, {"email": user.email})
51 if existing:
52 return {"error": "User with this email already exists"}
53
54 # Insert user
55 user_id = User.insert(db, user)
56 logger.info(f"User created successfully: {user.username}")
57
58 return {"success": True, "user_id": user_id, "user": user.dict()}
59
60 except ValidationError as e:
61 logger.error(f"User validation failed: {e}")
62 return {"error": "Invalid user data", "details": e.errors()}
63 except Exception as e:
64 logger.error(f"Failed to create user: {e}")
65 return {"error": "User creation failed", "details": str(e)}
66
67def update_user_safely(db, user_id, update_data):
68 """Update user with safety checks"""
69 try:
70 # Check if user exists
71 user = User.find(db, {"id": user_id})
72 if not user:
73 return {"error": f"User {user_id} not found"}
74
75 # Validate update data
76 current_data = user.dict()
77 current_data.update(update_data)
78 validated_user = User(**current_data)
79
80 # Perform update
81 result = User.update(db, {"id": user_id}, update_data)
82
83 if result:
84 logger.info(f"User {user_id} updated successfully")
85 return {"success": True, "user": validated_user.dict()}
86 else:
87 return {"error": "Update operation failed"}
88
89 except ValidationError as e:
90 return {"error": "Invalid update data", "details": e.errors()}
91 except Exception as e:
92 logger.error(f"Failed to update user {user_id}: {e}")
93 return {"error": "Update failed", "details": str(e)}
94
95# Transaction-like operations for multiple changes
96def transfer_article_ownership(db, article_id, new_author_id):
97 """Transfer article ownership with rollback capability"""
98 try:
99 # Verify article exists
100 article = Article.find(db, {"id": article_id})
101 if not article:
102 return {"error": "Article not found"}
103
104 # Verify new author exists
105 new_author = Author.find(db, {"id": new_author_id})
106 if not new_author:
107 return {"error": "New author not found"}
108
109 old_author_id = article.author_id
110
111 # Update article ownership
112 result = Article.update(
113 db,
114 {"id": article_id},
115 {"author_id": new_author_id, "updated_at": datetime.now().isoformat()}
116 )
117
118 if result:
119 logger.info(f"Article {article_id} transferred from author {old_author_id} to {new_author_id}")
120 return {"success": True, "old_author": old_author_id, "new_author": new_author_id}
121 else:
122 return {"error": "Transfer failed"}
123
124 except Exception as e:
125 logger.error(f"Article transfer failed: {e}")
126 return {"error": "Transfer operation failed", "details": str(e)}
127
128# Usage examples
129db_url = "sqlite:///blog.db"
130db = get_database_safely(db_url)
131
132if db:
133 # Safe user creation
134 result = create_user_safely(db, {
135 "id": 1,
136 "username": "testuser",
137 "email": "test@example.com",
138 "age": 25,
139 "created_at": datetime.now()
140 })
141 print(result)
142
143 # Safe user update
144 result = update_user_safely(db, 1, {"age": 26})
145 print(result)
146else:
147 print("Failed to connect to database")