or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

analysis-runner.mdconfiguration.mdexceptions.mdfile-finding.mdformatters.mdindex.mdmessages.mdprofiles.mdtools.md

exceptions.mddocs/

0

# Exceptions

1

2

Custom exception classes for error handling and diagnostics. Prospector defines several specific exceptions for different error conditions that can occur during analysis.

3

4

## Capabilities

5

6

### Core Exceptions

7

8

```python { .api }

9

class FatalProspectorException(Exception):

10

def __init__(self, message: str) -> None

11

```

12

13

Exception used to indicate an internal prospector problem or fatal error that prevents analysis from continuing.

14

15

**Parameters:**

16

- `message`: str - Description of the fatal error

17

18

**Properties:**

19

- `message`: str - The error message

20

21

This exception is raised for critical errors such as:

22

- Tool configuration failures that prevent execution

23

- Internal prospector errors that cannot be recovered

24

- Missing required dependencies for essential functionality

25

- Fatal errors triggered by the `--die-on-tool-error` flag

26

27

**Usage:** When this exception is raised, Prospector will typically exit with code 2 to indicate a fatal error rather than normal analysis completion.

28

29

```python { .api }

30

class CouldNotHandleEncoding(Exception):

31

def __init__(self, path: Path) -> None

32

```

33

34

Exception raised when Prospector cannot determine or handle the encoding of a source file.

35

36

**Parameters:**

37

- `path`: Path - Path to the file with encoding issues

38

39

**Properties:**

40

- `path`: Path - The problematic file path

41

42

This exception occurs when:

43

- A file contains invalid byte sequences for its declared encoding

44

- The file encoding cannot be detected automatically

45

- Character encoding conversion fails

46

47

```python { .api }

48

class PermissionMissing(Exception):

49

def __init__(self, path: Path) -> None

50

```

51

52

Exception raised when Prospector lacks permissions to read a file or directory.

53

54

**Parameters:**

55

- `path`: Path - Path to the inaccessible file or directory

56

57

The exception message includes:

58

- Information about the current user and the inaccessible path

59

- Suggestions for fixing permissions or using ignore patterns

60

- Link to documentation about ignoring paths

61

62

This exception provides helpful guidance for resolving permission issues by either:

63

- Fixing file/directory permissions

64

- Adding the path to `--ignore-paths` command line option

65

- Adding the path to `ignore-paths` in a prospector profile

66

67

### Profile-Related Exceptions

68

69

```python { .api }

70

class ProfileNotFound(Exception):

71

def __init__(self, name: str, profile_path: list[Path]) -> None

72

```

73

74

Exception raised when a requested configuration profile cannot be found.

75

76

**Parameters:**

77

- `name`: str - Name of the profile that wasn't found

78

- `profile_path`: list[Path] - List of paths that were searched

79

80

**Properties:**

81

- `name`: str - The profile name that was requested

82

- `profile_path`: list[Path] - The search paths that were checked

83

84

This exception occurs when:

85

- A profile specified with `--profile` doesn't exist

86

- A profile referenced in `inherits` cannot be found

87

- Profile search paths don't contain the requested profile

88

89

```python { .api }

90

class CannotParseProfile(Exception):

91

def __init__(self, filepath: Path, parse_error: Any) -> None

92

```

93

94

Exception raised when a profile file contains invalid YAML or configuration.

95

96

**Parameters:**

97

- `filepath`: Path - Path to the problematic profile file

98

- `parse_error`: Any - The underlying parsing error from the YAML parser

99

100

**Properties:**

101

- `filepath`: Path - The profile file that failed to parse

102

- `parse_error`: Any - The original parsing error

103

104

```python { .api }

105

def get_parse_message(self) -> str

106

```

107

108

Returns a human-readable error message describing the parse failure.

109

110

**Returns:**

111

- `str` - Formatted error message with details about the parsing problem

112

113

## Usage Examples

114

115

### Basic Exception Handling

116

117

```python

118

from prospector.config import ProspectorConfig

119

from prospector.run import Prospector

120

from prospector.exceptions import (

121

FatalProspectorException,

122

CouldNotHandleEncoding,

123

PermissionMissing

124

)

125

126

def run_analysis_safely():

127

try:

128

config = ProspectorConfig()

129

prospector = Prospector(config)

130

prospector.execute()

131

132

messages = prospector.get_messages()

133

print(f"Analysis completed: {len(messages)} issues found")

134

135

except FatalProspectorException as e:

136

print(f"Fatal error: {e.message}")

137

return 2 # Fatal error exit code

138

139

except CouldNotHandleEncoding as e:

140

print(f"Encoding error in file {e.path}")

141

print("Try specifying file encoding or excluding the file")

142

return 1

143

144

except PermissionMissing as e:

145

print(f"Permission denied: {e}")

146

return 1

147

148

except Exception as e:

149

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

150

return 1

151

152

return 0

153

154

exit_code = run_analysis_safely()

155

```

156

157

### Profile Exception Handling

158

159

```python

160

from prospector.profiles.profile import ProspectorProfile, ProfileNotFound, CannotParseProfile

161

from pathlib import Path

162

163

def load_profile_with_fallback(profile_name: str, search_paths: list[Path]) -> ProspectorProfile:

164

try:

165

profile = ProspectorProfile.load(profile_name, search_paths)

166

print(f"Loaded profile: {profile_name}")

167

return profile

168

169

except ProfileNotFound as e:

170

print(f"Profile '{e.name}' not found in any of these locations:")

171

for path in e.profile_path:

172

print(f" {path}")

173

174

# Fall back to default profile

175

print("Falling back to default profile")

176

return ProspectorProfile.load("default", search_paths)

177

178

except CannotParseProfile as e:

179

print(f"Failed to parse profile file: {e.filepath}")

180

print("Parse error details:")

181

print(e.get_parse_message())

182

183

# Could fall back to default or re-raise

184

raise

185

186

# Usage

187

search_paths = [Path(".prospector"), Path("/etc/prospector/profiles")]

188

profile = load_profile_with_fallback("myproject", search_paths)

189

```

190

191

### File Processing Error Handling

192

193

```python

194

from prospector.finder import FileFinder

195

from prospector.exceptions import CouldNotHandleEncoding, PermissionMissing

196

from pathlib import Path

197

198

def process_files_safely(paths: list[Path]):

199

try:

200

finder = FileFinder(*paths)

201

modules = list(finder.iter_all_modules())

202

203

processed_count = 0

204

error_count = 0

205

206

for module_path in modules:

207

try:

208

# Simulate file processing that might fail

209

with open(module_path, 'r', encoding='utf-8') as f:

210

content = f.read()

211

processed_count += 1

212

213

except UnicodeDecodeError:

214

print(f"Encoding error in {module_path}")

215

error_count += 1

216

217

except PermissionError:

218

print(f"Permission denied: {module_path}")

219

error_count += 1

220

221

print(f"Processed {processed_count} files, {error_count} errors")

222

223

except FileNotFoundError as e:

224

print(f"Path not found: {e}")

225

except Exception as e:

226

print(f"Unexpected error during file processing: {e}")

227

228

# Usage

229

process_files_safely([Path("src"), Path("tests")])

230

```

231

232

### Tool Error Handling

233

234

```python

235

from prospector.config import ProspectorConfig

236

from prospector.run import Prospector

237

from prospector.exceptions import FatalProspectorException

238

239

def run_with_error_tolerance():

240

# Configure to continue on tool errors (default behavior)

241

config = ProspectorConfig()

242

243

# If you want to fail fast on any tool error, set die_on_tool_error

244

# This would be done via command line: --die-on-tool-error

245

246

prospector = Prospector(config)

247

248

try:

249

prospector.execute()

250

251

messages = prospector.get_messages()

252

summary = prospector.get_summary()

253

254

# Check if any tools failed

255

if summary and "external_config" in summary:

256

print(f"External config used: {summary['external_config']}")

257

258

# Look for tool failure messages

259

tool_failures = [msg for msg in messages if msg.code == "failure"]

260

if tool_failures:

261

print(f"Warning: {len(tool_failures)} tools failed to run")

262

for failure in tool_failures:

263

print(f" {failure.source}: {failure.message}")

264

265

return messages

266

267

except FatalProspectorException as e:

268

print(f"Tool error caused fatal failure: {e.message}")

269

raise

270

271

messages = run_with_error_tolerance()

272

```

273

274

### Custom Exception Handling

275

276

```python

277

from prospector.exceptions import FatalProspectorException

278

import logging

279

280

class ProspectorRunner:

281

def __init__(self):

282

self.logger = logging.getLogger(__name__)

283

284

def run_analysis(self, config_overrides=None):

285

try:

286

from prospector.config import ProspectorConfig

287

from prospector.run import Prospector

288

289

config = ProspectorConfig()

290

prospector = Prospector(config)

291

prospector.execute()

292

293

return {

294

'success': True,

295

'messages': prospector.get_messages(),

296

'summary': prospector.get_summary()

297

}

298

299

except FatalProspectorException as e:

300

self.logger.error(f"Fatal prospector error: {e.message}")

301

return {

302

'success': False,

303

'error': 'fatal',

304

'message': e.message

305

}

306

307

except Exception as e:

308

self.logger.exception("Unexpected error during analysis")

309

return {

310

'success': False,

311

'error': 'unexpected',

312

'message': str(e)

313

}

314

315

def handle_result(self, result):

316

if result['success']:

317

print(f"Analysis successful: {len(result['messages'])} issues")

318

return 0

319

else:

320

print(f"Analysis failed ({result['error']}): {result['message']}")

321

return 2 if result['error'] == 'fatal' else 1

322

323

# Usage

324

runner = ProspectorRunner()

325

result = runner.run_analysis()

326

exit_code = runner.handle_result(result)

327

```

328

329

### Exception Context and Debugging

330

331

```python

332

from prospector.config import ProspectorConfig

333

from prospector.run import Prospector

334

from prospector.exceptions import FatalProspectorException

335

import traceback

336

337

def debug_prospector_error():

338

try:

339

config = ProspectorConfig()

340

prospector = Prospector(config)

341

prospector.execute()

342

343

except FatalProspectorException as e:

344

print("=== FATAL PROSPECTOR ERROR ===")

345

print(f"Error message: {e.message}")

346

print(f"Error type: {type(e).__name__}")

347

348

# Print full traceback for debugging

349

print("\nFull traceback:")

350

traceback.print_exc()

351

352

# Additional debug information

353

print(f"\nConfiguration summary:")

354

print(f" Tools to run: {config.tools_to_run}")

355

print(f" Paths: {config.paths}")

356

print(f" Working directory: {config.workdir}")

357

358

except Exception as e:

359

print("=== UNEXPECTED ERROR ===")

360

print(f"Error: {e}")

361

print(f"Type: {type(e).__name__}")

362

traceback.print_exc()

363

364

debug_prospector_error()

365

```