0
# Exception Handling
1
2
Comprehensive exception hierarchy for handling various configuration parsing and access errors. The configparser library provides specific exceptions for different error conditions to enable precise error handling.
3
4
## Capabilities
5
6
### Base Exception
7
8
Root exception class for all configparser-related errors.
9
10
```python { .api }
11
class Error(Exception):
12
"""
13
Base class for all configparser exceptions.
14
15
All other configparser exceptions inherit from this base class,
16
allowing for comprehensive error catching.
17
"""
18
```
19
20
### Section-Related Exceptions
21
22
Exceptions related to section operations and validation.
23
24
```python { .api }
25
class NoSectionError(Error):
26
"""
27
Raised when a specified section is not found.
28
29
Attributes:
30
- section: str, the name of the missing section
31
"""
32
33
class DuplicateSectionError(Error):
34
"""
35
Raised when attempting to add a section that already exists.
36
37
Occurs when strict=True and a duplicate section is encountered.
38
39
Attributes:
40
- section: str, the name of the duplicate section
41
- source: str, the source where duplication occurred
42
- lineno: int, line number where duplication occurred
43
"""
44
```
45
46
### Option-Related Exceptions
47
48
Exceptions related to option operations and validation.
49
50
```python { .api }
51
class NoOptionError(Error):
52
"""
53
Raised when a specified option is not found in a section.
54
55
Attributes:
56
- option: str, the name of the missing option
57
- section: str, the name of the section
58
"""
59
60
class DuplicateOptionError(Error):
61
"""
62
Raised when attempting to add an option that already exists.
63
64
Occurs when strict=True and a duplicate option is encountered.
65
66
Attributes:
67
- option: str, the name of the duplicate option
68
- section: str, the name of the section
69
- source: str, the source where duplication occurred
70
- lineno: int, line number where duplication occurred
71
"""
72
```
73
74
### Interpolation Exceptions
75
76
Exceptions related to value interpolation and substitution.
77
78
```python { .api }
79
class InterpolationError(Error):
80
"""
81
Base class for interpolation-related errors.
82
83
Attributes:
84
- option: str, the option being interpolated
85
- section: str, the section containing the option
86
"""
87
88
class InterpolationMissingOptionError(InterpolationError):
89
"""
90
Raised when interpolation references a non-existent option.
91
92
Attributes:
93
- option: str, the option being interpolated
94
- section: str, the section containing the option
95
- rawval: str, the raw value containing the bad reference
96
- reference: str, the missing option reference
97
"""
98
99
class InterpolationSyntaxError(InterpolationError):
100
"""
101
Raised when interpolation syntax is malformed.
102
103
Attributes:
104
- option: str, the option being interpolated
105
- section: str, the section containing the option
106
- msg: str, description of the syntax error
107
"""
108
109
class InterpolationDepthError(InterpolationError):
110
"""
111
Raised when interpolation recursion exceeds maximum depth.
112
113
Attributes:
114
- option: str, the option being interpolated
115
- section: str, the section containing the option
116
- rawval: str, the raw value causing deep recursion
117
"""
118
```
119
120
### Parsing Exceptions
121
122
Exceptions related to configuration file parsing.
123
124
```python { .api }
125
class ParsingError(Error):
126
"""
127
Raised when configuration file parsing fails.
128
129
Can contain multiple individual parsing errors from a single source.
130
131
Attributes:
132
- source: str, the source being parsed (filename, '<string>', etc.)
133
- errors: list of tuple, (filename, lineno, line) for each error
134
"""
135
136
class MissingSectionHeaderError(ParsingError):
137
"""
138
Raised when an option appears before any section header.
139
140
Attributes:
141
- source: str, the source being parsed
142
- lineno: int, line number of the problematic line
143
- line: str, the content of the problematic line
144
"""
145
146
class MultilineContinuationError(ParsingError):
147
"""
148
Raised when multiline value continuation is malformed.
149
150
Attributes:
151
- source: str, the source being parsed
152
- lineno: int, line number of the problematic line
153
- line: str, the content of the problematic line
154
"""
155
```
156
157
### Other Exceptions
158
159
Additional exceptions for specific error conditions.
160
161
```python { .api }
162
class UnnamedSectionDisabledError(Error):
163
"""
164
Raised when options without section are encountered but disabled.
165
166
Occurs when allow_unnamed_section=False and options appear
167
before any section header.
168
"""
169
170
class InvalidWriteError(Error):
171
"""
172
Raised when write operation cannot be completed.
173
174
Typically occurs when configuration state is invalid for writing.
175
"""
176
```
177
178
## Usage Examples
179
180
### Basic Exception Handling
181
182
```python
183
from backports import configparser
184
185
config = configparser.ConfigParser()
186
187
try:
188
config.read('config.ini')
189
value = config.get('database', 'host')
190
except configparser.NoSectionError:
191
print("Database section not found")
192
config.add_section('database')
193
config.set('database', 'host', 'localhost')
194
except configparser.NoOptionError:
195
print("Host option not found in database section")
196
config.set('database', 'host', 'localhost')
197
```
198
199
### Handling Multiple Error Types
200
201
```python
202
from backports import configparser
203
204
config = configparser.ConfigParser(strict=True)
205
206
try:
207
config.read_string('''
208
[section1]
209
option1 = value1
210
211
[section1] # Duplicate section
212
option2 = value2
213
''')
214
except configparser.DuplicateSectionError as e:
215
print(f"Duplicate section '{e.section}' at line {e.lineno}")
216
print(f"Source: {e.source}")
217
218
try:
219
config.read_string('''
220
[section]
221
option = value
222
option = another_value # Duplicate option
223
''')
224
except configparser.DuplicateOptionError as e:
225
print(f"Duplicate option '{e.option}' in section '{e.section}'")
226
print(f"At line {e.lineno} in {e.source}")
227
```
228
229
### Interpolation Error Handling
230
231
```python
232
from backports import configparser
233
234
config = configparser.ConfigParser()
235
236
config.read_string('''
237
[section]
238
valid_option = hello
239
broken_reference = %(missing_option)s
240
syntax_error = %(incomplete_reference
241
recursive_a = %(recursive_b)s
242
recursive_b = %(recursive_a)s
243
''')
244
245
# Handle missing reference
246
try:
247
value = config.get('section', 'broken_reference')
248
except configparser.InterpolationMissingOptionError as e:
249
print(f"Missing option '{e.reference}' referenced in '{e.option}'")
250
print(f"Raw value: {e.rawval}")
251
252
# Handle syntax error
253
try:
254
value = config.get('section', 'syntax_error')
255
except configparser.InterpolationSyntaxError as e:
256
print(f"Syntax error in '{e.option}': {e.msg}")
257
258
# Handle recursion depth
259
try:
260
value = config.get('section', 'recursive_a')
261
except configparser.InterpolationDepthError as e:
262
print(f"Recursion too deep in '{e.option}'")
263
print(f"Raw value: {e.rawval}")
264
```
265
266
### Parsing Error Handling
267
268
```python
269
from backports import configparser
270
271
config = configparser.ConfigParser()
272
273
try:
274
config.read_string('''
275
option_without_section = value # Error: no section header
276
277
[section]
278
valid_option = value
279
''')
280
except configparser.MissingSectionHeaderError as e:
281
print(f"Missing section header at line {e.lineno}")
282
print(f"Problematic line: {e.line}")
283
284
# Handle multiple parsing errors
285
malformed_config = '''
286
option1 = value1 # No section header
287
[section
288
option2 = value2 # Missing closing bracket
289
invalid line without equals
290
'''
291
292
try:
293
config.read_string(malformed_config)
294
except configparser.ParsingError as e:
295
print(f"Parsing failed for {e.source}")
296
for filename, lineno, line in e.errors:
297
print(f" Line {lineno}: {line}")
298
```
299
300
### Comprehensive Error Handling
301
302
```python
303
from backports import configparser
304
305
def safe_config_read(filename):
306
"""Safely read configuration with comprehensive error handling."""
307
config = configparser.ConfigParser()
308
309
try:
310
files_read = config.read(filename)
311
if not files_read:
312
print(f"Warning: Configuration file {filename} not found")
313
return None
314
315
except configparser.ParsingError as e:
316
print(f"Failed to parse {e.source}:")
317
for source, lineno, line in e.errors:
318
print(f" Line {lineno}: {line.strip()}")
319
return None
320
321
except Exception as e:
322
print(f"Unexpected error reading configuration: {e}")
323
return None
324
325
return config
326
327
def safe_get_value(config, section, option, converter=None, fallback=None):
328
"""Safely get configuration value with error handling."""
329
try:
330
if converter:
331
return converter(config.get(section, option))
332
return config.get(section, option)
333
334
except configparser.NoSectionError:
335
print(f"Section '{section}' not found")
336
return fallback
337
338
except configparser.NoOptionError:
339
print(f"Option '{option}' not found in section '{section}'")
340
return fallback
341
342
except (configparser.InterpolationError, ValueError) as e:
343
print(f"Error processing '{section}.{option}': {e}")
344
return fallback
345
346
# Usage
347
config = safe_config_read('app.ini')
348
if config:
349
host = safe_get_value(config, 'database', 'host', fallback='localhost')
350
port = safe_get_value(config, 'database', 'port', int, fallback=5432)
351
debug = safe_get_value(config, 'app', 'debug',
352
lambda x: x.lower() == 'true', fallback=False)
353
```
354
355
### Exception Hierarchy Catching
356
357
```python
358
from backports import configparser
359
360
config = configparser.ConfigParser()
361
362
# Catch all configparser exceptions
363
try:
364
config.read('config.ini')
365
value = config.get('section', 'option')
366
except configparser.Error as e:
367
print(f"ConfigParser error: {e}")
368
# Handle any configparser-specific error
369
370
# Catch specific interpolation errors
371
try:
372
value = config.get('section', 'interpolated_option')
373
except configparser.InterpolationError as e:
374
print(f"Interpolation error: {e}")
375
# Handle any interpolation-related error
376
```