0
# Error Handling
1
2
Comprehensive exception hierarchy providing specific error types for different filesystem operation failures. PyFileSystem2's error handling enables robust applications by providing detailed information about failure conditions.
3
4
## Capabilities
5
6
### Base Exception Classes
7
8
Root exception classes that define the error hierarchy structure.
9
10
```python { .api }
11
class FSError(Exception):
12
"""
13
Base class for all filesystem errors.
14
15
All PyFileSystem2 exceptions inherit from this class, allowing
16
applications to catch all filesystem-related errors with a single
17
except clause.
18
"""
19
20
def __init__(self, msg: str = None, details: Dict[str, Any] = None) -> None:
21
"""
22
Create filesystem error.
23
24
Parameters:
25
- msg: str, error message
26
- details: Dict[str, Any], additional error details
27
"""
28
29
class CreateFailed(FSError):
30
"""Failed to create a resource (file or directory)."""
31
pass
32
33
class ResourceError(FSError):
34
"""Base class for resource-related errors."""
35
36
def __init__(self, path: str, msg: str = None, details: Dict[str, Any] = None) -> None:
37
"""
38
Create resource error.
39
40
Parameters:
41
- path: str, path that caused the error
42
- msg: str, error message
43
- details: Dict[str, Any], additional error details
44
"""
45
```
46
47
### Resource Existence Errors
48
49
Errors related to resource existence and conflicts.
50
51
```python { .api }
52
class ResourceNotFound(ResourceError):
53
"""
54
Resource (file or directory) was not found.
55
56
Raised when attempting to access a resource that doesn't exist.
57
"""
58
pass
59
60
class ResourceExists(ResourceError):
61
"""
62
Resource already exists when it shouldn't.
63
64
Raised when attempting to create a resource that already exists
65
and overwrite is not allowed.
66
"""
67
pass
68
69
class DirectoryExists(ResourceExists):
70
"""
71
Directory already exists.
72
73
Raised when attempting to create a directory that already exists.
74
"""
75
pass
76
77
class FileExists(ResourceExists):
78
"""
79
File already exists.
80
81
Raised when attempting to create a file that already exists.
82
"""
83
pass
84
```
85
86
### Resource Type Errors
87
88
Errors when the wrong resource type is encountered.
89
90
```python { .api }
91
class DirectoryExpected(ResourceError):
92
"""
93
Expected a directory but found a file.
94
95
Raised when a directory operation is attempted on a file.
96
"""
97
pass
98
99
class FileExpected(ResourceError):
100
"""
101
Expected a file but found a directory.
102
103
Raised when a file operation is attempted on a directory.
104
"""
105
pass
106
```
107
108
### Permission and Access Errors
109
110
Errors related to filesystem permissions and access rights.
111
112
```python { .api }
113
class PermissionDenied(ResourceError):
114
"""
115
Permission denied for filesystem operation.
116
117
Raised when the current user lacks sufficient permissions
118
to perform the requested operation.
119
"""
120
pass
121
122
class DirectoryNotEmpty(ResourceError):
123
"""
124
Directory is not empty when it should be.
125
126
Raised when attempting to remove a directory that contains files
127
or subdirectories.
128
"""
129
pass
130
```
131
132
### System and Network Errors
133
134
Errors related to system resources and network connectivity.
135
136
```python { .api }
137
class RemoteConnectionError(FSError):
138
"""
139
Failed to connect to remote filesystem.
140
141
Raised when network filesystems (FTP, etc.) cannot establish
142
or maintain a connection.
143
"""
144
pass
145
146
class InsufficientStorage(FSError):
147
"""
148
Insufficient storage space available.
149
150
Raised when a write operation fails due to lack of available
151
storage space.
152
"""
153
pass
154
155
class FilesystemClosed(FSError):
156
"""
157
Filesystem has been closed.
158
159
Raised when attempting to perform operations on a closed filesystem.
160
"""
161
pass
162
```
163
164
### Operation Errors
165
166
Errors related to specific filesystem operations.
167
168
```python { .api }
169
class OperationFailed(FSError):
170
"""
171
Generic operation failure.
172
173
Raised when a filesystem operation fails for reasons not covered
174
by more specific exception types.
175
"""
176
pass
177
178
class OperationTimeout(FSError):
179
"""
180
Operation timed out.
181
182
Raised when a filesystem operation takes longer than the specified
183
timeout period.
184
"""
185
pass
186
187
class Unsupported(FSError):
188
"""
189
Operation not supported by this filesystem.
190
191
Raised when attempting an operation that the filesystem
192
implementation doesn't support.
193
"""
194
pass
195
196
class CrossDeviceError(FSError):
197
"""
198
Cross-device operation not supported.
199
200
Raised when attempting to move files across different filesystems
201
or devices where atomic operations are not possible.
202
"""
203
pass
204
```
205
206
### Path and URL Errors
207
208
Errors related to path validation and URL parsing.
209
210
```python { .api }
211
class IllegalBackReference(FSError):
212
"""
213
Illegal back reference in path.
214
215
Raised when a path contains '..' components that would escape
216
the filesystem root.
217
"""
218
pass
219
220
class InvalidPath(FSError):
221
"""
222
Path is invalid for this filesystem.
223
224
Raised when a path contains characters or patterns not supported
225
by the filesystem.
226
"""
227
pass
228
229
class InvalidCharsInPath(InvalidPath):
230
"""
231
Path contains invalid characters.
232
233
Raised when a path contains characters that are not allowed
234
by the filesystem (e.g., null bytes, control characters).
235
"""
236
pass
237
238
class NoSysPath(FSError):
239
"""
240
No system path available for resource.
241
242
Raised when getsyspath() is called on a filesystem that doesn't
243
map to system paths (e.g., memory filesystems, archives).
244
"""
245
pass
246
247
class NoURL(FSError):
248
"""
249
No URL available for resource.
250
251
Raised when geturl() is called on a filesystem that doesn't
252
support URLs for resources.
253
"""
254
pass
255
```
256
257
### Opener Errors
258
259
Errors related to filesystem opening and URL parsing.
260
261
```python { .api }
262
class OpenerError(FSError):
263
"""Base class for opener-related errors."""
264
pass
265
266
class UnsupportedProtocol(OpenerError):
267
"""
268
Protocol not supported by any opener.
269
270
Raised when attempting to open a filesystem with a URL scheme
271
that no registered opener can handle.
272
"""
273
pass
274
275
class ParseError(OpenerError):
276
"""
277
Failed to parse filesystem URL.
278
279
Raised when a filesystem URL cannot be parsed into valid components.
280
"""
281
pass
282
```
283
284
## Usage Examples
285
286
Basic error handling:
287
288
```python
289
from fs import open_fs
290
from fs.errors import FSError, ResourceNotFound, PermissionDenied
291
292
try:
293
fs = open_fs('.')
294
content = fs.readtext('nonexistent.txt')
295
except ResourceNotFound as e:
296
print(f"File not found: {e.path}")
297
except PermissionDenied as e:
298
print(f"Permission denied: {e.path}")
299
except FSError as e:
300
print(f"Filesystem error: {e}")
301
```
302
303
Handling specific error types:
304
305
```python
306
from fs import open_fs
307
from fs.errors import DirectoryExists, FileExists, DirectoryExpected
308
309
fs = open_fs('.')
310
311
# Handle directory creation errors
312
try:
313
fs.makedir('new_directory')
314
except DirectoryExists:
315
print("Directory already exists")
316
except FSError as e:
317
print(f"Failed to create directory: {e}")
318
319
# Handle file vs directory confusion
320
try:
321
fs.listdir('some_file.txt')
322
except DirectoryExpected:
323
print("Expected directory, got file")
324
except ResourceNotFound:
325
print("Path doesn't exist")
326
```
327
328
Network filesystem error handling:
329
330
```python
331
from fs import open_fs
332
from fs.errors import RemoteConnectionError, OperationTimeout
333
334
try:
335
ftp_fs = open_fs('ftp://user:pass@example.com/')
336
files = ftp_fs.listdir('/')
337
except RemoteConnectionError as e:
338
print(f"Failed to connect to FTP server: {e}")
339
except OperationTimeout as e:
340
print(f"FTP operation timed out: {e}")
341
except FSError as e:
342
print(f"FTP filesystem error: {e}")
343
```
344
345
Comprehensive error handling for file operations:
346
347
```python
348
from fs import open_fs
349
from fs.errors import (
350
ResourceNotFound, ResourceExists, PermissionDenied,
351
DirectoryExpected, FileExpected, InsufficientStorage,
352
FilesystemClosed
353
)
354
355
def safe_copy_file(src_fs, src_path, dst_fs, dst_path):
356
"""Safely copy file with comprehensive error handling."""
357
try:
358
# Check if source exists and is a file
359
if not src_fs.exists(src_path):
360
raise ResourceNotFound(src_path)
361
if not src_fs.isfile(src_path):
362
raise FileExpected(src_path)
363
364
# Check if destination already exists
365
if dst_fs.exists(dst_path):
366
raise ResourceExists(dst_path)
367
368
# Perform the copy
369
src_fs.copy(src_path, dst_fs, dst_path)
370
return True
371
372
except ResourceNotFound as e:
373
print(f"Source file not found: {e.path}")
374
except FileExpected as e:
375
print(f"Source is not a file: {e.path}")
376
except ResourceExists as e:
377
print(f"Destination already exists: {e.path}")
378
except PermissionDenied as e:
379
print(f"Permission denied: {e.path}")
380
except InsufficientStorage as e:
381
print(f"Not enough storage space: {e}")
382
except FilesystemClosed as e:
383
print(f"Filesystem is closed: {e}")
384
except FSError as e:
385
print(f"Copy failed: {e}")
386
387
return False
388
```
389
390
Error details and debugging:
391
392
```python
393
from fs import open_fs
394
from fs.errors import FSError
395
396
try:
397
fs = open_fs('invalid://bad-url')
398
except FSError as e:
399
print(f"Error message: {e}")
400
print(f"Error type: {type(e).__name__}")
401
402
# Some errors include additional details
403
if hasattr(e, 'details') and e.details:
404
print(f"Error details: {e.details}")
405
406
# Resource errors include the problematic path
407
if hasattr(e, 'path'):
408
print(f"Path: {e.path}")
409
```
410
411
## Types
412
413
```python { .api }
414
from typing import Dict, Any, Optional
415
416
# Error details dictionary type
417
ErrorDetails = Dict[str, Any]
418
419
# Common error attributes
420
class FSError(Exception):
421
msg: Optional[str]
422
details: Optional[ErrorDetails]
423
424
class ResourceError(FSError):
425
path: str
426
```