or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-models.mddataclasses-adapters.mderror-handling.mdindex.mdjson-schema.mdplugins.mdserialization-config.mdtype-system.mdvalidation-system.md

error-handling.mddocs/

0

# Error Handling and Utilities

1

2

Exception classes, warning system, and utility functions for advanced pydantic usage patterns.

3

4

## Capabilities

5

6

### Exception Classes

7

8

Pydantic-specific exception classes for handling validation and configuration errors.

9

10

```python { .api }

11

class ValidationError(ValueError):

12

"""

13

Raised when validation fails.

14

15

Contains detailed information about validation failures.

16

"""

17

18

def __init__(self, errors, model=PydanticUndefined):

19

"""

20

Initialize validation error.

21

22

Args:

23

errors: List of error dictionaries

24

model: Model class that failed validation

25

"""

26

27

def errors(self, *, include_url=True, include_context=True):

28

"""

29

Get list of error dictionaries.

30

31

Args:

32

include_url (bool): Include error documentation URLs

33

include_context (bool): Include error context

34

35

Returns:

36

list: List of error dictionaries

37

"""

38

39

def error_count(self):

40

"""

41

Get total number of errors.

42

43

Returns:

44

int: Number of validation errors

45

"""

46

47

@property

48

def title(self):

49

"""str: Error title based on model name"""

50

51

class PydanticUserError(TypeError):

52

"""

53

Raised when user makes an error in pydantic usage.

54

55

Indicates incorrect usage of pydantic APIs or configuration.

56

"""

57

58

class PydanticUndefinedAnnotation(AttributeError):

59

"""

60

Raised when a field annotation is undefined or cannot be resolved.

61

"""

62

63

class PydanticSchemaGenerationError(TypeError):

64

"""

65

Raised when JSON schema generation fails.

66

"""

67

68

class PydanticImportError(ImportError):

69

"""

70

Raised when required imports are missing for optional features.

71

"""

72

73

class PydanticInvalidForJsonSchema(TypeError):

74

"""

75

Raised when a type cannot be represented in JSON schema.

76

"""

77

```

78

79

### Warning Classes

80

81

Warning classes for deprecated features and potential issues.

82

83

```python { .api }

84

class PydanticDeprecatedSince20(UserWarning):

85

"""

86

Warning for features deprecated since pydantic v2.0.

87

"""

88

89

class PydanticExperimentalWarning(UserWarning):

90

"""

91

Warning for experimental features that may change.

92

"""

93

```

94

95

### Utility Functions

96

97

Utility functions for working with pydantic models and types.

98

99

```python { .api }

100

def __version__():

101

"""

102

Get pydantic version string.

103

104

Returns:

105

str: Version string (e.g., "2.11.7")

106

"""

107

108

def compiled():

109

"""

110

Check if pydantic is running with compiled extensions.

111

112

Returns:

113

bool: True if compiled extensions are available

114

"""

115

116

class PydanticUndefined:

117

"""

118

Sentinel value for undefined/missing values.

119

120

Used internally to distinguish between None and undefined.

121

"""

122

123

def parse_obj_as(type_, obj):

124

"""

125

Parse object as specified type (legacy function).

126

127

Args:

128

type_: Type to parse as

129

obj: Object to parse

130

131

Returns:

132

Parsed object

133

134

Note:

135

Deprecated: Use TypeAdapter.validate_python() instead

136

"""

137

138

def schema_of(type_, *, title='Generated schema'):

139

"""

140

Generate schema for type (legacy function).

141

142

Args:

143

type_: Type to generate schema for

144

title (str): Schema title

145

146

Returns:

147

dict: Type schema

148

149

Note:

150

Deprecated: Use TypeAdapter.json_schema() instead

151

"""

152

153

def schema_json_of(type_, *, title='Generated schema', indent=2):

154

"""

155

Generate JSON schema string for type (legacy function).

156

157

Args:

158

type_: Type to generate schema for

159

title (str): Schema title

160

indent (int): JSON indentation

161

162

Returns:

163

str: JSON schema string

164

165

Note:

166

Deprecated: Use TypeAdapter.json_schema() instead

167

"""

168

```

169

170

### Error Context and Formatting

171

172

Advanced error handling utilities for better error reporting.

173

174

```python { .api }

175

class ErrorWrapper:

176

"""

177

Wrapper for validation errors with additional context.

178

"""

179

180

def __init__(self, exc, loc):

181

"""

182

Initialize error wrapper.

183

184

Args:

185

exc: Exception to wrap

186

loc: Location tuple for the error

187

"""

188

189

def format_errors(errors, *, model_name=None):

190

"""

191

Format validation errors for display.

192

193

Args:

194

errors: List of error dictionaries

195

model_name (str): Model name for context

196

197

Returns:

198

str: Formatted error message

199

"""

200

```

201

202

## Usage Examples

203

204

### Handling ValidationError

205

206

```python

207

from pydantic import BaseModel, ValidationError, Field

208

from typing import List

209

210

class User(BaseModel):

211

id: int = Field(..., gt=0)

212

name: str = Field(..., min_length=1, max_length=50)

213

email: str = Field(..., regex=r'^[\w\.-]+@[\w\.-]+\.\w+$')

214

age: int = Field(..., ge=0, le=150)

215

216

# Handle validation errors

217

try:

218

invalid_user = User(

219

id=-1, # Invalid: must be > 0

220

name="", # Invalid: too short

221

email="invalid", # Invalid: bad format

222

age=200 # Invalid: too high

223

)

224

except ValidationError as e:

225

print(f"Validation failed with {e.error_count()} errors:")

226

227

for error in e.errors():

228

field = " -> ".join(str(loc) for loc in error['loc'])

229

message = error['msg']

230

value = error.get('input', 'N/A')

231

print(f" {field}: {message} (got: {value})")

232

233

# Output:

234

# Validation failed with 4 errors:

235

# id: Input should be greater than 0 (got: -1)

236

# name: String should have at least 1 character (got: )

237

# email: String should match pattern '^[\w\.-]+@[\w\.-]+\.\w+$' (got: invalid)

238

# age: Input should be less than or equal to 150 (got: 200)

239

```

240

241

### Custom Error Messages

242

243

```python

244

from pydantic import BaseModel, Field, field_validator, ValidationError

245

246

class Product(BaseModel):

247

name: str = Field(..., min_length=1, description="Product name")

248

price: float = Field(..., gt=0, description="Product price in USD")

249

category: str

250

251

@field_validator('category')

252

@classmethod

253

def validate_category(cls, v):

254

allowed = ['electronics', 'clothing', 'books', 'home']

255

if v.lower() not in allowed:

256

raise ValueError(f'Category must be one of: {", ".join(allowed)}')

257

return v.lower()

258

259

try:

260

product = Product(

261

name="",

262

price=-10,

263

category="invalid_category"

264

)

265

except ValidationError as e:

266

# Print detailed error information

267

for error in e.errors():

268

print(f"Field: {error['loc']}")

269

print(f"Error: {error['msg']}")

270

print(f"Type: {error['type']}")

271

if 'ctx' in error:

272

print(f"Context: {error['ctx']}")

273

print("---")

274

```

275

276

### Nested Validation Errors

277

278

```python

279

from pydantic import BaseModel, ValidationError

280

from typing import List

281

282

class Address(BaseModel):

283

street: str

284

city: str

285

zip_code: str = Field(..., regex=r'^\d{5}(-\d{4})?$')

286

287

class User(BaseModel):

288

name: str

289

addresses: List[Address]

290

291

try:

292

user_data = {

293

'name': 'John',

294

'addresses': [

295

{'street': '123 Main St', 'city': 'Anytown', 'zip_code': 'invalid'},

296

{'street': '', 'city': 'Other City', 'zip_code': '12345'}

297

]

298

}

299

user = User(**user_data)

300

except ValidationError as e:

301

for error in e.errors():

302

# Error location shows nested path

303

location = ' -> '.join(str(loc) for loc in error['loc'])

304

print(f"{location}: {error['msg']}")

305

306

# Output:

307

# addresses -> 0 -> zip_code: String should match pattern '^\d{5}(-\d{4})?$'

308

# addresses -> 1 -> street: String should have at least 1 character

309

```

310

311

### Error Context and URLs

312

313

```python

314

from pydantic import BaseModel, ValidationError, Field

315

316

class Config(BaseModel):

317

timeout: int = Field(..., ge=1, le=3600)

318

max_connections: int = Field(..., ge=1, le=1000)

319

320

try:

321

config = Config(timeout=0, max_connections=2000)

322

except ValidationError as e:

323

# Get errors with full context and URLs

324

for error in e.errors(include_url=True, include_context=True):

325

print(f"Field: {error['loc']}")

326

print(f"Error: {error['msg']}")

327

print(f"Input: {error['input']}")

328

329

# Show constraint context if available

330

if 'ctx' in error:

331

print(f"Constraints: {error['ctx']}")

332

333

# Show documentation URL if available

334

if 'url' in error:

335

print(f"Help: {error['url']}")

336

print("---")

337

```

338

339

### Using PydanticUserError

340

341

```python

342

from pydantic import BaseModel, Field, PydanticUserError

343

344

class MyModel(BaseModel):

345

value: int

346

347

@classmethod

348

def create_with_validation(cls, **kwargs):

349

"""Factory method with additional validation."""

350

351

# Check for deprecated usage patterns

352

if 'old_field' in kwargs:

353

raise PydanticUserError(

354

"The 'old_field' parameter is no longer supported. "

355

"Use 'value' instead."

356

)

357

358

return cls(**kwargs)

359

360

# This would raise PydanticUserError

361

try:

362

model = MyModel.create_with_validation(old_field=42)

363

except PydanticUserError as e:

364

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

365

```

366

367

### Checking for Compiled Extensions

368

369

```python

370

from pydantic import compiled

371

372

if compiled:

373

print("Pydantic is running with compiled Rust extensions for better performance")

374

else:

375

print("Pydantic is running in pure Python mode")

376

print("Consider installing with: pip install pydantic[email]")

377

```

378

379

### Custom Error Formatting

380

381

```python

382

from pydantic import BaseModel, ValidationError, Field

383

import json

384

385

class ErrorFormatter:

386

@staticmethod

387

def format_validation_error(error: ValidationError) -> dict:

388

"""Format ValidationError for API responses."""

389

formatted_errors = []

390

391

for err in error.errors():

392

formatted_errors.append({

393

'field': '.'.join(str(loc) for loc in err['loc']),

394

'message': err['msg'],

395

'type': err['type'],

396

'value': err.get('input')

397

})

398

399

return {

400

'error': 'validation_failed',

401

'message': f'Validation failed with {error.error_count()} errors',

402

'details': formatted_errors

403

}

404

405

class User(BaseModel):

406

email: str = Field(..., regex=r'^[\w\.-]+@[\w\.-]+\.\w+$')

407

age: int = Field(..., ge=0, le=150)

408

409

try:

410

user = User(email='invalid-email', age=-5)

411

except ValidationError as e:

412

error_response = ErrorFormatter.format_validation_error(e)

413

print(json.dumps(error_response, indent=2))

414

```

415

416

### Legacy Function Migration

417

418

```python

419

from pydantic import parse_obj_as, schema_of, TypeAdapter, ValidationError

420

from typing import List, Dict

421

422

# Old way (deprecated)

423

try:

424

result = parse_obj_as(List[int], ['1', '2', '3'])

425

schema = schema_of(List[int])

426

except Exception as e:

427

print(f"Legacy function error: {e}")

428

429

# New way (recommended)

430

adapter = TypeAdapter(List[int])

431

try:

432

result = adapter.validate_python(['1', '2', '3'])

433

schema = adapter.json_schema()

434

print(f"Result: {result}")

435

print(f"Schema keys: {list(schema.keys())}")

436

except ValidationError as e:

437

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

438

```