0
# Error Handling & Exceptions
1
2
Comprehensive exception hierarchy for handling different types of errors that can occur during certificate operations, plugin usage, and configuration management.
3
4
## Capabilities
5
6
### Base Error Classes
7
8
Foundation exception classes that provide the base hierarchy for all Certbot errors.
9
10
```python { .api }
11
class Error(Exception):
12
"""
13
Generic Certbot client error.
14
15
Base class for all Certbot-specific exceptions.
16
"""
17
18
class ReverterError(Error):
19
"""
20
Certbot Reverter error.
21
22
Raised when configuration backup/restore operations fail.
23
"""
24
25
class SubprocessError(Error):
26
"""
27
Subprocess handling error.
28
29
Raised when external command execution fails.
30
"""
31
32
class SignalExit(Error):
33
"""
34
A Unix signal was received while in the ErrorHandler context manager.
35
36
Used to handle graceful shutdown on signals like SIGINT, SIGTERM.
37
"""
38
39
class LockError(Error):
40
"""
41
File locking error.
42
43
Raised when Certbot cannot acquire necessary file locks.
44
"""
45
46
class HookCommandNotFound(Error):
47
"""
48
Failed to find a hook command in the PATH.
49
50
Raised when pre/post/deploy hook commands cannot be executed.
51
"""
52
53
class OverlappingMatchFound(Error):
54
"""
55
Multiple lineages matched what should have been a unique result.
56
57
Raised when certificate selection is ambiguous.
58
"""
59
```
60
61
### Account Management Errors
62
63
Errors related to ACME account operations and storage.
64
65
```python { .api }
66
class AccountStorageError(Error):
67
"""
68
Generic account storage error.
69
70
Base class for account-related storage operations.
71
"""
72
73
class AccountNotFound(AccountStorageError):
74
"""
75
Account not found error.
76
77
Raised when trying to load an account that doesn't exist.
78
"""
79
```
80
81
Usage examples:
82
83
```python
84
from certbot import errors
85
86
try:
87
account = account_storage.load('nonexistent-account-id')
88
except errors.AccountNotFound:
89
print("Account does not exist")
90
except errors.AccountStorageError as e:
91
print(f"Account storage error: {e}")
92
```
93
94
### Authorization and Challenge Errors
95
96
Errors that occur during ACME authorization and challenge processes.
97
98
```python { .api }
99
class AuthorizationError(Error):
100
"""
101
Authorization error.
102
103
Base class for ACME authorization failures.
104
"""
105
106
class FailedChallenges(AuthorizationError):
107
"""
108
Failed challenges error.
109
110
Raised when one or more ACME challenges fail during authorization.
111
Contains information about which challenges failed and why.
112
"""
113
114
def __init__(self, failed_achalls: set[AnnotatedChallenge]):
115
"""
116
Initialize with failed challenges.
117
118
Args:
119
failed_achalls: Set of failed AnnotatedChallenge instances
120
"""
121
self.failed_achalls = failed_achalls
122
super().__init__()
123
124
def __str__(self) -> str:
125
"""
126
Return formatted error message with challenge details.
127
128
Returns:
129
Detailed error message listing failed challenges
130
"""
131
```
132
133
Usage examples:
134
135
```python
136
from certbot import errors
137
138
try:
139
# Perform ACME challenges
140
authenticator.perform(challenges)
141
except errors.FailedChallenges as e:
142
print("Challenge failures:")
143
for achall in e.failed_achalls:
144
print(f" Domain: {achall.domain}, Type: {achall.typ}, Error: {achall.error}")
145
except errors.AuthorizationError:
146
print("Authorization failed")
147
```
148
149
### Plugin Errors
150
151
Errors specific to plugin operations and development.
152
153
```python { .api }
154
class PluginError(Error):
155
"""
156
Certbot Plugin error.
157
158
Base class for plugin-related errors.
159
"""
160
161
class PluginSelectionError(Error):
162
"""
163
A problem with plugin/configurator selection or setup.
164
165
Raised when plugins cannot be loaded or configured properly.
166
"""
167
168
class MisconfigurationError(PluginError):
169
"""
170
Certbot Plugin misconfiguration error.
171
172
Raised when plugin configuration is invalid or incomplete.
173
"""
174
175
class NotSupportedError(PluginError):
176
"""
177
Certbot Plugin function not supported error.
178
179
Raised when attempting to use unsupported plugin functionality.
180
"""
181
182
class NoInstallationError(PluginError):
183
"""
184
Certbot No Installation error.
185
186
Raised when installer plugin cannot find supported software installation.
187
"""
188
189
class PluginStorageError(PluginError):
190
"""
191
Certbot Plugin Storage error.
192
193
Raised when plugin storage operations fail.
194
"""
195
196
class PluginEnhancementAlreadyPresent(Error):
197
"""
198
Enhancement was already set.
199
200
Raised when trying to apply an enhancement that's already configured.
201
"""
202
203
class StandaloneBindError(Error):
204
"""
205
Standalone plugin bind error.
206
207
Raised when standalone authenticator cannot bind to required ports.
208
"""
209
```
210
211
Usage examples:
212
213
```python
214
from certbot import errors
215
216
class MyPlugin:
217
def deploy_cert(self, domain, cert_path, key_path, chain_path, fullchain_path):
218
try:
219
# Deploy certificate logic
220
self._update_server_config(domain, cert_path, key_path)
221
except FileNotFoundError:
222
raise errors.NoInstallationError(
223
f"Server configuration not found for {domain}"
224
)
225
except PermissionError:
226
raise errors.PluginError(
227
"Insufficient permissions to update server configuration"
228
)
229
230
def enhance(self, domain, enhancement, options=None):
231
if enhancement not in self.supported_enhancements():
232
raise errors.NotSupportedError(
233
f"Enhancement '{enhancement}' is not supported"
234
)
235
236
if self._enhancement_exists(domain, enhancement):
237
raise errors.PluginEnhancementAlreadyPresent(
238
f"Enhancement '{enhancement}' already configured for {domain}"
239
)
240
```
241
242
### Certificate Storage Errors
243
244
Errors related to certificate storage and management.
245
246
```python { .api }
247
class CertStorageError(Error):
248
"""
249
Generic certificate storage error.
250
251
Raised when certificate storage operations fail.
252
"""
253
```
254
255
Usage example:
256
257
```python
258
from certbot import errors
259
260
try:
261
# Save certificate to storage
262
cert_storage.save(domain, cert_data)
263
except errors.CertStorageError as e:
264
print(f"Failed to store certificate: {e}")
265
```
266
267
## Error Handling Patterns
268
269
### Try-Catch Patterns
270
271
Common patterns for handling Certbot errors:
272
273
```python
274
from certbot import errors
275
276
# Handle specific plugin errors
277
try:
278
plugin.deploy_cert(domain, cert_path, key_path, chain_path, fullchain_path)
279
except errors.NoInstallationError:
280
print("Web server not found - manual configuration required")
281
except errors.MisconfigurationError as e:
282
print(f"Configuration error: {e}")
283
except errors.PluginError as e:
284
print(f"Plugin error: {e}")
285
286
# Handle challenge failures
287
try:
288
responses = authenticator.perform(challenges)
289
except errors.FailedChallenges as e:
290
for achall in e.failed_achalls:
291
if achall.error:
292
print(f"Challenge failed for {achall.domain}: {achall.error}")
293
except errors.AuthorizationError:
294
print("Authorization process failed")
295
296
# Handle account operations
297
try:
298
account = account_storage.load(account_id)
299
except errors.AccountNotFound:
300
print("Account not found - creating new account")
301
account = account_storage.create_new_account()
302
except errors.AccountStorageError as e:
303
print(f"Account storage error: {e}")
304
```
305
306
### Error Context Information
307
308
Many Certbot errors include additional context information:
309
310
```python
311
# FailedChallenges provides detailed failure information
312
try:
313
authenticator.perform(challenges)
314
except errors.FailedChallenges as e:
315
for achall in e.failed_achalls:
316
print(f"Failed challenge:")
317
print(f" Domain: {achall.domain}")
318
print(f" Challenge type: {achall.typ}")
319
print(f" Error: {achall.error}")
320
print(f" Status: {achall.status}")
321
322
# Plugin errors often include configuration details
323
try:
324
plugin.config_test()
325
except errors.MisconfigurationError as e:
326
print(f"Configuration test failed: {e}")
327
# Error message includes specific configuration issues
328
```
329
330
### Custom Error Handling
331
332
When developing plugins, create informative error messages:
333
334
```python
335
from certbot import errors
336
337
class MyAuthenticator:
338
def perform(self, achalls):
339
for achall in achalls:
340
try:
341
self._create_challenge_response(achall)
342
except ConnectionError:
343
raise errors.PluginError(
344
f"Cannot connect to DNS provider API for domain {achall.domain}. "
345
f"Check network connectivity and API credentials."
346
)
347
except ValueError as e:
348
raise errors.MisconfigurationError(
349
f"Invalid configuration for domain {achall.domain}: {e}"
350
)
351
```