or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aggregations-helpers.mdattributes-relationships.mddata-types.mddatabase-entities.mddebugging-utilities.mdexception-handling.mdframework-integrations.mdindex.mdquery-operations.mdsecurity-permissions.mdsession-management.md

exception-handling.mddocs/

0

# Exception Handling

1

2

Comprehensive exception hierarchy covering database errors, ORM-specific errors, query errors, and transaction errors. Proper exception handling is crucial for building robust applications with Pony ORM.

3

4

## Capabilities

5

6

### ORM-Level Exceptions

7

8

Core ORM exceptions that handle entity operations, queries, and object lifecycle errors.

9

10

```python { .api }

11

class OrmError(Exception):

12

"""Base exception class for all ORM-related errors."""

13

14

class ObjectNotFound(OrmError):

15

"""Raised when get() or [] operator finds no matching entity."""

16

17

class MultipleObjectsFoundError(OrmError):

18

"""Raised when get() finds multiple entities when expecting one."""

19

20

class TooManyObjectsFoundError(MultipleObjectsFoundError):

21

"""Raised when query returns more objects than expected limit."""

22

23

class OperationWithDeletedObjectError(OrmError):

24

"""Raised when attempting operations on deleted entity objects."""

25

26

class CacheIndexError(OrmError):

27

"""Raised when entity cache index operations fail."""

28

29

class MappingError(OrmError):

30

"""Raised when entity mapping or schema definition is invalid."""

31

32

class ERDiagramError(OrmError):

33

"""Raised when entity relationship diagram generation fails."""

34

35

class BindingError(OrmError):

36

"""Raised when database binding or connection configuration fails."""

37

```

38

39

### Database-Level Exceptions

40

41

Standard database API exceptions that correspond to DB-API 2.0 specification errors.

42

43

```python { .api }

44

class DBException(Exception):

45

"""Base exception class for all database-related errors."""

46

47

class Warning(DBException):

48

"""Exception for important database warnings."""

49

50

class Error(DBException):

51

"""Base exception class for database errors."""

52

53

class InterfaceError(Error):

54

"""Exception for database interface errors."""

55

56

class DatabaseError(Error):

57

"""Exception for database-specific errors."""

58

59

class DataError(DatabaseError):

60

"""Exception for data processing errors (invalid data, numeric overflow, etc.)."""

61

62

class OperationalError(DatabaseError):

63

"""Exception for database operation errors (connection lost, memory allocation, etc.)."""

64

65

class IntegrityError(DatabaseError):

66

"""Exception for database constraint violations (foreign key, unique, etc.)."""

67

68

class InternalError(DatabaseError):

69

"""Exception for internal database errors."""

70

71

class ProgrammingError(DatabaseError):

72

"""Exception for programming errors (table not found, syntax error, etc.)."""

73

74

class NotSupportedError(DatabaseError):

75

"""Exception for unsupported database operations or methods."""

76

```

77

78

### Schema and Table Exceptions

79

80

Exceptions related to database schema operations and table management.

81

82

```python { .api }

83

class DBSchemaError(OrmError):

84

"""Raised when database schema operations fail."""

85

86

class TableDoesNotExist(DBSchemaError):

87

"""Raised when referencing non-existent database table."""

88

89

class TableIsNotEmpty(DBSchemaError):

90

"""Raised when attempting operations that require empty table."""

91

92

class ConstraintError(DBSchemaError):

93

"""Raised when database constraint operations fail."""

94

```

95

96

### Query and Result Exceptions

97

98

Exceptions specific to query operations and result processing.

99

100

```python { .api }

101

class RowNotFound(DBException):

102

"""Raised when database query returns no rows when expecting results."""

103

104

class MultipleRowsFound(DBException):

105

"""Raised when database query returns multiple rows when expecting one."""

106

107

class TooManyRowsFound(MultipleRowsFound):

108

"""Raised when query returns more rows than specified limit."""

109

```

110

111

### Transaction Exceptions

112

113

Exceptions related to transaction management and concurrency control.

114

115

```python { .api }

116

class TransactionError(OrmError):

117

"""Base exception class for transaction-related errors."""

118

119

class ConnectionClosedError(TransactionError):

120

"""Raised when database connection is unexpectedly closed."""

121

122

class TransactionIntegrityError(TransactionError):

123

"""Raised when transaction integrity is compromised."""

124

125

class IsolationError(TransactionError):

126

"""Raised when transaction isolation level conflicts occur."""

127

128

class CommitException(TransactionError):

129

"""Raised when transaction commit operation fails."""

130

131

class RollbackException(TransactionError):

132

"""Raised when transaction rollback operation fails."""

133

134

class UnrepeatableReadError(TransactionError):

135

"""Raised when repeatable read isolation is violated."""

136

137

class OptimisticCheckError(TransactionError):

138

"""Raised when optimistic concurrency control check fails."""

139

140

class UnresolvableCyclicDependency(TransactionError):

141

"""Raised when circular dependencies prevent transaction completion."""

142

143

class UnexpectedError(TransactionError):

144

"""Raised for unexpected transaction-related errors."""

145

146

class DatabaseSessionIsOver(TransactionError):

147

"""Raised when attempting operations outside active database session."""

148

```

149

150

### Translation and Runtime Exceptions

151

152

Exceptions related to query translation and runtime operations.

153

154

```python { .api }

155

class TranslationError(OrmError):

156

"""Raised when generator expression cannot be translated to SQL."""

157

158

class ExprEvalError(OrmError):

159

"""Raised when expression evaluation fails during query processing."""

160

161

class PonyRuntimeWarning(UserWarning):

162

"""Warning class for runtime issues that don't prevent execution."""

163

164

class DatabaseContainsIncorrectValue(PonyRuntimeWarning):

165

"""Warning when database contains values that don't match expected format."""

166

167

class DatabaseContainsIncorrectEmptyValue(PonyRuntimeWarning):

168

"""Warning when database contains empty values in unexpected contexts."""

169

```

170

171

### Security and Permission Exceptions

172

173

Exceptions related to security and access control operations.

174

175

```python { .api }

176

class PermissionError(OrmError):

177

"""Raised when security permission checks fail."""

178

```

179

180

## Usage Examples

181

182

### Basic Exception Handling

183

184

```python

185

from pony.orm import *

186

187

@db_session

188

def safe_user_lookup(email):

189

try:

190

user = User.get(email=email)

191

return user

192

except ObjectNotFound:

193

print(f"No user found with email: {email}")

194

return None

195

except MultipleObjectsFoundError:

196

print(f"Multiple users found with email: {email}")

197

# This shouldn't happen if email is unique

198

raise

199

200

@db_session

201

def handle_entity_operations():

202

try:

203

# Try to create user

204

user = User(name="Alice", email="alice@example.com")

205

commit()

206

207

except IntegrityError as e:

208

print(f"Database constraint violation: {e}")

209

rollback()

210

# Handle duplicate email, etc.

211

212

except DatabaseError as e:

213

print(f"Database error occurred: {e}")

214

rollback()

215

raise

216

```

217

218

### Transaction Exception Handling

219

220

```python

221

@db_session

222

def handle_transaction_errors():

223

try:

224

# Risky operations that might conflict

225

user = User.get(name="Alice")

226

user.balance += 100

227

228

# Force a flush to detect conflicts early

229

flush()

230

231

# More operations...

232

order = Order(user=user, total=50.0)

233

commit()

234

235

except OptimisticCheckError as e:

236

print(f"Concurrent modification detected: {e}")

237

rollback()

238

# Retry logic or user notification

239

240

except ConnectionClosedError as e:

241

print(f"Database connection lost: {e}")

242

# Reconnection logic

243

244

except TransactionError as e:

245

print(f"Transaction failed: {e}")

246

rollback()

247

raise

248

249

# Retry pattern for handling optimistic concurrency

250

def retry_on_conflict(func, max_retries=3):

251

for attempt in range(max_retries):

252

try:

253

return func()

254

except OptimisticCheckError:

255

if attempt == max_retries - 1:

256

raise

257

print(f"Retry attempt {attempt + 1}")

258

# Brief delay before retry

259

import time

260

time.sleep(0.1 * (attempt + 1))

261

```

262

263

### Query Exception Handling

264

265

```python

266

@db_session

267

def safe_query_operations():

268

try:

269

# Query that might return no results

270

admin = User.get(role="admin")

271

272

except ObjectNotFound:

273

print("No admin user found, creating default admin")

274

admin = User(name="Admin", role="admin", email="admin@example.com")

275

276

try:

277

# Query that might return multiple results unexpectedly

278

primary_contact = Contact.get(is_primary=True, company_id=123)

279

280

except MultipleObjectsFoundError:

281

print("Multiple primary contacts found, using first one")

282

primary_contact = Contact.select(

283

lambda c: c.is_primary and c.company_id == 123

284

).first()

285

286

except ObjectNotFound:

287

print("No primary contact found")

288

primary_contact = None

289

290

# Handle translation errors for complex queries

291

@db_session

292

def handle_query_translation():

293

try:

294

# Complex query that might not translate properly

295

result = select(u for u in User

296

if some_complex_python_function(u.data))

297

298

except TranslationError as e:

299

print(f"Query cannot be translated to SQL: {e}")

300

# Fall back to Python filtering

301

all_users = User.select()

302

result = [u for u in all_users

303

if some_complex_python_function(u.data)]

304

```

305

306

### Schema and Database Exception Handling

307

308

```python

309

def handle_database_setup():

310

try:

311

db.bind('postgresql', host='localhost', user='app', password='secret')

312

db.generate_mapping(create_tables=True)

313

314

except BindingError as e:

315

print(f"Failed to bind to database: {e}")

316

# Try fallback database

317

db.bind('sqlite', filename='fallback.db')

318

db.generate_mapping(create_tables=True)

319

320

except TableDoesNotExist as e:

321

print(f"Required table missing: {e}")

322

# Create missing tables

323

db.create_tables()

324

325

except DBSchemaError as e:

326

print(f"Schema error: {e}")

327

# Handle schema migration or recreation

328

329

except DatabaseError as e:

330

print(f"Database operation failed: {e}")

331

raise

332

333

@db_session

334

def handle_table_operations():

335

try:

336

# Operation that requires empty table

337

db.execute("TRUNCATE TABLE user_sessions")

338

339

except TableIsNotEmpty as e:

340

print(f"Cannot truncate non-empty table: {e}")

341

# Delete rows individually

342

delete(s for s in UserSession)

343

344

except ProgrammingError as e:

345

print(f"SQL programming error: {e}")

346

# Handle SQL syntax issues

347

```

348

349

### Comprehensive Error Handling Pattern

350

351

```python

352

from functools import wraps

353

354

def safe_db_operation(func):

355

"""Decorator for comprehensive database error handling."""

356

@wraps(func)

357

def wrapper(*args, **kwargs):

358

try:

359

return func(*args, **kwargs)

360

361

except ObjectNotFound as e:

362

print(f"Entity not found in {func.__name__}: {e}")

363

return None

364

365

except MultipleObjectsFoundError as e:

366

print(f"Multiple entities found in {func.__name__}: {e}")

367

raise

368

369

except IntegrityError as e:

370

print(f"Database constraint violation in {func.__name__}: {e}")

371

rollback()

372

raise

373

374

except OptimisticCheckError as e:

375

print(f"Concurrent modification in {func.__name__}: {e}")

376

rollback()

377

raise

378

379

except TransactionError as e:

380

print(f"Transaction error in {func.__name__}: {e}")

381

rollback()

382

raise

383

384

except DatabaseError as e:

385

print(f"Database error in {func.__name__}: {e}")

386

rollback()

387

raise

388

389

except Exception as e:

390

print(f"Unexpected error in {func.__name__}: {e}")

391

rollback()

392

raise

393

394

return wrapper

395

396

# Usage of the decorator

397

@safe_db_operation

398

@db_session

399

def update_user_profile(user_id, **updates):

400

user = User[user_id] # May raise ObjectNotFound

401

for key, value in updates.items():

402

setattr(user, key, value)

403

commit()

404

return user

405

```

406

407

### Warning and Runtime Error Handling

408

409

```python

410

import warnings

411

412

# Handle runtime warnings

413

def handle_warnings():

414

# Catch Pony runtime warnings

415

with warnings.catch_warnings(record=True) as w:

416

warnings.simplefilter("always")

417

418

with db_session:

419

# Operations that might generate warnings

420

problematic_data = select(u for u in User if u.data_field)

421

422

for warning in w:

423

if issubclass(warning.category, PonyRuntimeWarning):

424

print(f"Pony warning: {warning.message}")

425

# Handle data quality issues

426

427

@db_session

428

def handle_expression_errors():

429

try:

430

# Complex expression that might fail evaluation

431

result = select(u.calculate_score() for u in User)

432

433

except ExprEvalError as e:

434

print(f"Expression evaluation failed: {e}")

435

# Fall back to safer calculation

436

result = select(u for u in User)

437

scores = [u.calculate_score() for u in result]

438

```