or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-classes.mdexception-handling.mdindex.mdutilities.md

exception-handling.mddocs/

0

# Exception Handling

1

2

Error handling mechanisms and logging utilities for FUSE filesystem implementations. These provide structured error reporting and debugging capabilities for filesystem operations.

3

4

## Capabilities

5

6

### FuseOSError Exception

7

8

The primary exception class for FUSE-related errors, providing errno-based error reporting that integrates with the FUSE kernel interface.

9

10

```python { .api }

11

class FuseOSError(OSError):

12

"""Exception class for FUSE-related OS errors."""

13

14

def __init__(self, errno):

15

"""

16

Create a FUSE OS error.

17

18

Args:

19

errno: Error number (from errno module constants)

20

"""

21

```

22

23

#### Usage Examples

24

25

```python

26

import errno

27

from mfusepy import FuseOSError, Operations

28

29

class MyFilesystem(Operations):

30

def getattr(self, path, fh=None):

31

if path not in self.files:

32

# File not found

33

raise FuseOSError(errno.ENOENT)

34

35

if not self._has_permission(path, 'read'):

36

# Permission denied

37

raise FuseOSError(errno.EACCES)

38

39

return self.files[path]

40

41

def mkdir(self, path, mode):

42

if path in self.files:

43

# File already exists

44

raise FuseOSError(errno.EEXIST)

45

46

parent = os.path.dirname(path)

47

if parent not in self.files:

48

# Parent directory doesn't exist

49

raise FuseOSError(errno.ENOENT)

50

51

# Create directory

52

self.files[path] = {'st_mode': mode | 0x4000, 'st_nlink': 2}

53

return 0

54

```

55

56

#### Common Error Codes

57

58

```python

59

import errno

60

61

# File system errors commonly used with FuseOSError:

62

errno.ENOENT # No such file or directory

63

errno.EACCES # Permission denied

64

errno.EEXIST # File exists

65

errno.EISDIR # Is a directory

66

errno.ENOTDIR # Not a directory

67

errno.ENOTEMPTY # Directory not empty

68

errno.ENOSPC # No space left on device

69

errno.EROFS # Read-only file system

70

errno.EIO # I/O error

71

errno.EFBIG # File too large

72

errno.ENOSYS # Function not implemented

73

errno.EINVAL # Invalid argument

74

```

75

76

### LoggingMixIn

77

78

A mixin class that automatically logs all filesystem operation calls and their results, useful for debugging and monitoring filesystem implementations.

79

80

```python { .api }

81

class LoggingMixIn:

82

"""Mixin class for logging all Operation callbacks."""

83

```

84

85

#### Usage Example

86

87

```python

88

from mfusepy import Operations, LoggingMixIn, FUSE

89

import logging

90

91

# Configure logging

92

logging.basicConfig(level=logging.DEBUG)

93

94

class MyFS(LoggingMixIn, Operations):

95

"""Filesystem with automatic logging."""

96

97

def __init__(self):

98

self.files = {'/': {'st_mode': 0o755 | 0x4000, 'st_nlink': 2}}

99

100

def getattr(self, path, fh=None):

101

if path in self.files:

102

return self.files[path]

103

raise FuseOSError(errno.ENOENT)

104

105

def readdir(self, path, fh):

106

return ['.', '..'] + [name[1:] for name in self.files if name != '/']

107

108

# Mount with logging - all operations will be automatically logged

109

filesystem = MyFS()

110

fuse = FUSE(filesystem, '/mnt/myfs', foreground=True)

111

112

# Log output will show:

113

# DEBUG:fuse.log-mixin:-> getattr / None

114

# DEBUG:fuse.log-mixin:<- getattr {'st_mode': 16877, 'st_nlink': 2}

115

```

116

117

## Decorators

118

119

Utility decorators for method validation and logging in filesystem implementations.

120

121

```python { .api }

122

from typing import Callable

123

124

def log_callback(method: Callable) -> Callable:

125

"""

126

Decorator that adds log output for the decorated method.

127

128

Args:

129

method: Method to decorate

130

131

Returns:

132

Decorated method with logging

133

"""

134

135

def overrides(parent_class: type) -> Callable:

136

"""

137

Decorator that checks method exists in parent class.

138

139

Args:

140

parent_class: Parent class to check against

141

142

Returns:

143

Decorator function

144

"""

145

```

146

147

### Usage Examples

148

149

```python

150

from mfusepy import Operations, log_callback, overrides

151

152

class MyFS(Operations):

153

@overrides(Operations)

154

@log_callback

155

def getattr(self, path, fh=None):

156

# Implementation with automatic validation and logging

157

return {'st_mode': 0o644, 'st_nlink': 1, 'st_size': 0}

158

159

@log_callback

160

def custom_method(self):

161

# Custom method with logging

162

return "custom result"

163

```

164

165

## Error Handling Patterns

166

167

### Basic Error Handling

168

169

```python

170

from mfusepy import Operations, FuseOSError

171

import errno

172

import os

173

174

class RobustFS(Operations):

175

def getattr(self, path, fh=None):

176

try:

177

# Attempt to get file attributes

178

stat_result = self._get_file_stats(path)

179

return {

180

'st_mode': stat_result.mode,

181

'st_size': stat_result.size,

182

'st_nlink': stat_result.nlink,

183

}

184

except FileNotFoundError:

185

raise FuseOSError(errno.ENOENT)

186

except PermissionError:

187

raise FuseOSError(errno.EACCES)

188

except Exception as e:

189

# Log unexpected errors and return generic I/O error

190

self.logger.error(f"Unexpected error in getattr({path}): {e}")

191

raise FuseOSError(errno.EIO)

192

```

193

194

### Validation and Sanitization

195

196

```python

197

class SecureFS(Operations):

198

def _validate_path(self, path):

199

"""Validate and sanitize file paths."""

200

if not path.startswith('/'):

201

raise FuseOSError(errno.EINVAL)

202

203

# Prevent directory traversal

204

normalized = os.path.normpath(path)

205

if '..' in normalized or normalized != path:

206

raise FuseOSError(errno.EACCES)

207

208

return normalized

209

210

def _check_permissions(self, path, operation):

211

"""Check if operation is permitted on path."""

212

if not self._has_permission(path, operation):

213

raise FuseOSError(errno.EACCES)

214

215

def read(self, path, size, offset, fh):

216

path = self._validate_path(path)

217

self._check_permissions(path, 'read')

218

219

try:

220

return self._read_file_data(path, size, offset)

221

except IOError:

222

raise FuseOSError(errno.EIO)

223

```

224

225

### Resource Management

226

227

```python

228

class ResourceFS(Operations):

229

def __init__(self):

230

self.open_files = {}

231

self.max_open_files = 1000

232

233

def open(self, path, flags):

234

if len(self.open_files) >= self.max_open_files:

235

raise FuseOSError(errno.EMFILE) # Too many open files

236

237

try:

238

fh = self._allocate_file_handle()

239

self.open_files[fh] = self._open_file(path, flags)

240

return fh

241

except IOError:

242

raise FuseOSError(errno.EIO)

243

244

def release(self, path, fh):

245

try:

246

if fh in self.open_files:

247

self.open_files[fh].close()

248

del self.open_files[fh]

249

return 0

250

except Exception as e:

251

self.logger.warning(f"Error closing file handle {fh}: {e}")

252

return 0 # Don't propagate errors from release

253

```

254

255

## Logging Configuration

256

257

```python

258

import logging

259

from mfusepy import LoggingMixIn, Operations, FUSE

260

261

# Configure different log levels for different components

262

logging.getLogger('fuse').setLevel(logging.INFO)

263

logging.getLogger('fuse.log-mixin').setLevel(logging.DEBUG)

264

265

# Custom formatter for FUSE logs

266

formatter = logging.Formatter(

267

'%(asctime)s - %(name)s - %(levelname)s - %(message)s'

268

)

269

270

handler = logging.StreamHandler()

271

handler.setFormatter(formatter)

272

273

logger = logging.getLogger('fuse')

274

logger.addHandler(handler)

275

276

class MyFS(LoggingMixIn, Operations):

277

# Your filesystem implementation

278

pass

279

```