or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-types.mddocument-operations.mderror-handling.mdfile-operations.mdindex.mditem-classes.mditem-creation.md

error-handling.mddocs/

0

# Error Handling

1

2

Comprehensive exception hierarchy for parsing errors, validation failures, and runtime issues with detailed error reporting. TOML Kit provides specific exceptions for different error conditions to enable precise error handling.

3

4

## Capabilities

5

6

### Base Exception Classes

7

8

Foundation exception classes that other TOML Kit exceptions inherit from.

9

10

```python { .api }

11

class TOMLKitError(Exception):

12

"""Base exception class for all TOML Kit errors."""

13

14

class ParseError(ValueError, TOMLKitError):

15

"""

16

Base class for TOML parsing errors with position information.

17

18

Attributes:

19

- line: Line number where error occurred

20

- col: Column number where error occurred

21

"""

22

23

def __init__(self, line: int, col: int, message: str | None = None) -> None: ...

24

25

@property

26

def line(self) -> int:

27

"""Get the line number of the error."""

28

29

@property

30

def col(self) -> int:

31

"""Get the column number of the error."""

32

```

33

34

### Parsing Error Classes

35

36

Specific exceptions for different TOML syntax and parsing errors.

37

38

```python { .api }

39

class MixedArrayTypesError(ParseError):

40

"""Array contains elements of different types (invalid in TOML)."""

41

42

class InvalidNumberError(ParseError):

43

"""Numeric value has invalid format."""

44

45

class InvalidDateTimeError(ParseError):

46

"""DateTime value has invalid RFC3339 format."""

47

48

class InvalidDateError(ParseError):

49

"""Date value has invalid format (YYYY-MM-DD)."""

50

51

class InvalidTimeError(ParseError):

52

"""Time value has invalid format."""

53

54

class InvalidNumberOrDateError(ParseError):

55

"""Value cannot be parsed as number or date."""

56

57

class InvalidUnicodeValueError(ParseError):

58

"""Unicode escape sequence is invalid."""

59

60

class UnexpectedCharError(ParseError):

61

"""Unexpected character encountered during parsing."""

62

63

def __init__(self, line: int, col: int, char: str) -> None: ...

64

65

class EmptyKeyError(ParseError):

66

"""Key is empty or missing."""

67

68

class EmptyTableNameError(ParseError):

69

"""Table name is empty."""

70

71

class InvalidCharInStringError(ParseError):

72

"""String contains invalid character."""

73

74

def __init__(self, line: int, col: int, char: str) -> None: ...

75

76

class UnexpectedEofError(ParseError):

77

"""File ended unexpectedly during parsing."""

78

79

class InternalParserError(ParseError):

80

"""Internal parser error indicating a bug."""

81

82

class InvalidControlChar(ParseError):

83

"""String contains invalid control character."""

84

85

def __init__(self, line: int, col: int, char: int, type: str) -> None: ...

86

```

87

88

### Runtime Error Classes

89

90

Exceptions that occur during TOML document manipulation and conversion.

91

92

```python { .api }

93

class NonExistentKey(KeyError, TOMLKitError):

94

"""Attempted to access a key that doesn't exist."""

95

96

def __init__(self, key) -> None: ...

97

98

class KeyAlreadyPresent(TOMLKitError):

99

"""Attempted to add a key that already exists."""

100

101

def __init__(self, key) -> None: ...

102

103

class InvalidStringError(ValueError, TOMLKitError):

104

"""String value contains invalid character sequences."""

105

106

def __init__(self, value: str, invalid_sequences: Collection[str], delimiter: str) -> None: ...

107

108

class ConvertError(TypeError, ValueError, TOMLKitError):

109

"""Failed to convert Python value to TOML item."""

110

```

111

112

## Usage Examples

113

114

### Basic Error Handling

115

116

```python

117

import tomlkit

118

from tomlkit.exceptions import ParseError, TOMLKitError

119

120

def safe_parse(content: str):

121

"""Parse TOML with error handling."""

122

try:

123

return tomlkit.parse(content)

124

except ParseError as e:

125

print(f"Parse error at line {e.line}, column {e.col}: {e}")

126

return None

127

except TOMLKitError as e:

128

print(f"TOML Kit error: {e}")

129

return None

130

131

# Valid TOML

132

valid_toml = 'title = "My App"'

133

doc = safe_parse(valid_toml)

134

135

# Invalid TOML - syntax error

136

invalid_toml = 'title = "unclosed string'

137

doc = safe_parse(invalid_toml) # Prints error message

138

```

139

140

### Specific Parse Error Handling

141

142

```python

143

import tomlkit

144

from tomlkit.exceptions import (

145

InvalidNumberError, InvalidDateError, MixedArrayTypesError,

146

UnexpectedCharError, EmptyKeyError

147

)

148

149

def parse_with_specific_handling(content: str):

150

"""Handle specific parsing errors differently."""

151

try:

152

return tomlkit.parse(content)

153

except InvalidNumberError as e:

154

print(f"Invalid number format at line {e.line}: {e}")

155

# Could attempt to fix or provide suggestions

156

except InvalidDateError as e:

157

print(f"Invalid date format at line {e.line}: {e}")

158

# Could suggest correct date format

159

except MixedArrayTypesError as e:

160

print(f"Array has mixed types at line {e.line}: {e}")

161

# Could explain TOML array type rules

162

except UnexpectedCharError as e:

163

print(f"Unexpected character at line {e.line}, col {e.col}: {e}")

164

# Could highlight the problematic character

165

except EmptyKeyError as e:

166

print(f"Empty key at line {e.line}: {e}")

167

# Could suggest key naming rules

168

169

# Test different error types

170

test_cases = [

171

'number = 123.45.67', # InvalidNumberError

172

'date = 2023-13-01', # InvalidDateError

173

'mixed = [1, "text", true]', # MixedArrayTypesError

174

'key = value @', # UnexpectedCharError

175

' = "value"', # EmptyKeyError

176

]

177

178

for i, case in enumerate(test_cases):

179

print(f"\nTest case {i+1}:")

180

parse_with_specific_handling(case)

181

```

182

183

### Runtime Error Handling

184

185

```python

186

import tomlkit

187

from tomlkit.exceptions import NonExistentKey, KeyAlreadyPresent, ConvertError

188

189

def safe_document_operations():

190

"""Demonstrate runtime error handling."""

191

doc = tomlkit.document()

192

193

# Key access errors

194

try:

195

value = doc["nonexistent"]

196

except NonExistentKey as e:

197

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

198

199

# Key collision errors

200

doc["title"] = "My App"

201

try:

202

# Attempting to add existing key in certain contexts

203

doc.add("title", "Another Title")

204

except KeyAlreadyPresent as e:

205

print(f"Key already exists: {e}")

206

207

# Conversion errors

208

class CustomObject:

209

pass

210

211

try:

212

doc["custom"] = CustomObject() # Cannot convert to TOML

213

except ConvertError as e:

214

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

215

216

safe_document_operations()

217

```

218

219

### Error Recovery Strategies

220

221

```python

222

import tomlkit

223

from tomlkit.exceptions import ParseError, InvalidNumberError, InvalidDateError

224

import re

225

226

def parse_with_recovery(content: str):

227

"""Attempt to parse with error recovery strategies."""

228

try:

229

return tomlkit.parse(content)

230

except InvalidNumberError as e:

231

print(f"Attempting to fix number format error at line {e.line}")

232

# Simple recovery: remove extra decimal points

233

lines = content.split('\n')

234

line_content = lines[e.line - 1]

235

236

# Fix common number format issues

237

fixed_line = re.sub(r'(\d+\.\d+)\.\d+', r'\1', line_content)

238

lines[e.line - 1] = fixed_line

239

240

try:

241

return tomlkit.parse('\n'.join(lines))

242

except ParseError:

243

print("Recovery failed")

244

return None

245

246

except InvalidDateError as e:

247

print(f"Attempting to fix date format error at line {e.line}")

248

# Could implement date format corrections

249

return None

250

251

except ParseError as e:

252

print(f"Unrecoverable parse error: {e}")

253

return None

254

255

# Test recovery

256

problematic_toml = '''title = "Test"

257

version = 1.2.3.4

258

date = 2023-01-01'''

259

260

doc = parse_with_recovery(problematic_toml)

261

```

262

263

### Validation with Error Reporting

264

265

```python

266

import tomlkit

267

from tomlkit.exceptions import TOMLKitError

268

from typing import List, Tuple

269

270

def validate_config(content: str) -> Tuple[bool, List[str]]:

271

"""Validate TOML configuration and return errors."""

272

errors = []

273

274

try:

275

doc = tomlkit.parse(content)

276

except ParseError as e:

277

errors.append(f"Syntax error at line {e.line}, col {e.col}: {str(e)}")

278

return False, errors

279

280

# Custom validation rules

281

try:

282

# Check required fields

283

if "title" not in doc:

284

errors.append("Missing required field: title")

285

286

if "version" not in doc:

287

errors.append("Missing required field: version")

288

289

# Validate types

290

if "port" in doc and not isinstance(doc["port"], int):

291

errors.append("Port must be an integer")

292

293

# Validate ranges

294

if "port" in doc and not (1 <= doc["port"] <= 65535):

295

errors.append("Port must be between 1 and 65535")

296

297

except (KeyError, TypeError, ValueError) as e:

298

errors.append(f"Validation error: {e}")

299

300

return len(errors) == 0, errors

301

302

# Test validation

303

configs = [

304

'title = "Valid App"\nversion = "1.0"\nport = 8080',

305

'title = "Invalid App"\nport = "not a number"',

306

'version = "1.0"\nport = 70000', # Missing title, invalid port

307

]

308

309

for i, config in enumerate(configs):

310

valid, errors = validate_config(config)

311

print(f"\nConfig {i+1}: {'Valid' if valid else 'Invalid'}")

312

for error in errors:

313

print(f" - {error}")

314

```

315

316

### Error Logging and Debugging

317

318

```python

319

import tomlkit

320

from tomlkit.exceptions import ParseError, TOMLKitError

321

import logging

322

323

# Set up logging

324

logging.basicConfig(level=logging.INFO)

325

logger = logging.getLogger(__name__)

326

327

def parse_with_logging(content: str, source: str = ""):

328

"""Parse TOML with comprehensive error logging."""

329

try:

330

doc = tomlkit.parse(content)

331

logger.info(f"Successfully parsed TOML from {source}")

332

return doc

333

334

except ParseError as e:

335

# Log detailed parse error information

336

lines = content.split('\n')

337

error_line = lines[e.line - 1] if e.line <= len(lines) else ""

338

339

logger.error(f"Parse error in {source}:")

340

logger.error(f" Line {e.line}, Column {e.col}: {str(e)}")

341

logger.error(f" Content: {error_line}")

342

logger.error(f" Position: {' ' * (e.col - 1)}^")

343

344

# Additional context

345

start_line = max(0, e.line - 3)

346

end_line = min(len(lines), e.line + 2)

347

348

logger.error("Context:")

349

for i in range(start_line, end_line):

350

marker = ">>>" if i == e.line - 1 else " "

351

logger.error(f" {marker} {i+1:3d}: {lines[i]}")

352

353

except TOMLKitError as e:

354

logger.error(f"TOML Kit error in {source}: {str(e)}")

355

356

except Exception as e:

357

logger.error(f"Unexpected error parsing {source}: {str(e)}")

358

359

return None

360

361

# Test with logging

362

test_content = '''title = "Test App"

363

version = 1.0.0

364

invalid_syntax = @#$%

365

host = "localhost"'''

366

367

doc = parse_with_logging(test_content, "test-config.toml")

368

```

369

370

### Exception Hierarchies for Different Handling

371

372

```python

373

import tomlkit

374

from tomlkit.exceptions import *

375

376

def categorized_error_handling(content: str):

377

"""Handle errors by category."""

378

try:

379

return tomlkit.parse(content)

380

381

except (InvalidNumberError, InvalidDateError, InvalidTimeError,

382

InvalidDateTimeError, InvalidNumberOrDateError) as e:

383

# Data format errors - might be recoverable

384

print(f"Data format error: {e}")

385

print("Consider checking date/time/number formats")

386

return None

387

388

except (EmptyKeyError, EmptyTableNameError, InvalidCharInStringError) as e:

389

# Structural errors - usually need manual fix

390

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

391

print("Check TOML syntax and key naming")

392

return None

393

394

except (UnexpectedCharError, UnexpectedEofError) as e:

395

# Syntax errors - need content review

396

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

397

print("Review TOML syntax")

398

return None

399

400

except ParseError as e:

401

# General parse errors

402

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

403

return None

404

405

except (NonExistentKey, KeyAlreadyPresent) as e:

406

# Runtime errors - programming issues

407

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

408

return None

409

410

except TOMLKitError as e:

411

# Any other TOML Kit error

412

print(f"TOML Kit error: {e}")

413

return None

414

415

# Test different error categories

416

test_cases = [

417

'date = 2023-99-99', # Data format error

418

' = "empty key"', # Structure error

419

'key = "value" @', # Syntax error

420

]

421

422

for case in test_cases:

423

categorized_error_handling(case)

424

```