CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-prospector

Prospector is a tool to analyse Python code by aggregating the result of other tools.

Pending
Overview
Eval results
Files

exceptions.mddocs/

Exceptions

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

Capabilities

Core Exceptions

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

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

Parameters:

  • message: str - Description of the fatal error

Properties:

  • message: str - The error message

This exception is raised for critical errors such as:

  • Tool configuration failures that prevent execution
  • Internal prospector errors that cannot be recovered
  • Missing required dependencies for essential functionality
  • Fatal errors triggered by the --die-on-tool-error flag

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

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

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

Parameters:

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

Properties:

  • path: Path - The problematic file path

This exception occurs when:

  • A file contains invalid byte sequences for its declared encoding
  • The file encoding cannot be detected automatically
  • Character encoding conversion fails
class PermissionMissing(Exception):
    def __init__(self, path: Path) -> None

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

Parameters:

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

The exception message includes:

  • Information about the current user and the inaccessible path
  • Suggestions for fixing permissions or using ignore patterns
  • Link to documentation about ignoring paths

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

  • Fixing file/directory permissions
  • Adding the path to --ignore-paths command line option
  • Adding the path to ignore-paths in a prospector profile

Profile-Related Exceptions

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

Exception raised when a requested configuration profile cannot be found.

Parameters:

  • name: str - Name of the profile that wasn't found
  • profile_path: list[Path] - List of paths that were searched

Properties:

  • name: str - The profile name that was requested
  • profile_path: list[Path] - The search paths that were checked

This exception occurs when:

  • A profile specified with --profile doesn't exist
  • A profile referenced in inherits cannot be found
  • Profile search paths don't contain the requested profile
class CannotParseProfile(Exception):
    def __init__(self, filepath: Path, parse_error: Any) -> None

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

Parameters:

  • filepath: Path - Path to the problematic profile file
  • parse_error: Any - The underlying parsing error from the YAML parser

Properties:

  • filepath: Path - The profile file that failed to parse
  • parse_error: Any - The original parsing error
def get_parse_message(self) -> str

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

Returns:

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

Usage Examples

Basic Exception Handling

from prospector.config import ProspectorConfig
from prospector.run import Prospector
from prospector.exceptions import (
    FatalProspectorException,
    CouldNotHandleEncoding,
    PermissionMissing
)

def run_analysis_safely():
    try:
        config = ProspectorConfig()
        prospector = Prospector(config)
        prospector.execute()
        
        messages = prospector.get_messages()
        print(f"Analysis completed: {len(messages)} issues found")
        
    except FatalProspectorException as e:
        print(f"Fatal error: {e.message}")
        return 2  # Fatal error exit code
        
    except CouldNotHandleEncoding as e:
        print(f"Encoding error in file {e.path}")
        print("Try specifying file encoding or excluding the file")
        return 1
        
    except PermissionMissing as e:
        print(f"Permission denied: {e}")
        return 1
        
    except Exception as e:
        print(f"Unexpected error: {e}")
        return 1
    
    return 0

exit_code = run_analysis_safely()

Profile Exception Handling

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

def load_profile_with_fallback(profile_name: str, search_paths: list[Path]) -> ProspectorProfile:
    try:
        profile = ProspectorProfile.load(profile_name, search_paths)
        print(f"Loaded profile: {profile_name}")
        return profile
        
    except ProfileNotFound as e:
        print(f"Profile '{e.name}' not found in any of these locations:")
        for path in e.profile_path:
            print(f"  {path}")
        
        # Fall back to default profile
        print("Falling back to default profile")
        return ProspectorProfile.load("default", search_paths)
        
    except CannotParseProfile as e:
        print(f"Failed to parse profile file: {e.filepath}")
        print("Parse error details:")
        print(e.get_parse_message())
        
        # Could fall back to default or re-raise
        raise

# Usage
search_paths = [Path(".prospector"), Path("/etc/prospector/profiles")]
profile = load_profile_with_fallback("myproject", search_paths)

File Processing Error Handling

from prospector.finder import FileFinder
from prospector.exceptions import CouldNotHandleEncoding, PermissionMissing
from pathlib import Path

def process_files_safely(paths: list[Path]):
    try:
        finder = FileFinder(*paths)
        modules = list(finder.iter_all_modules())
        
        processed_count = 0
        error_count = 0
        
        for module_path in modules:
            try:
                # Simulate file processing that might fail
                with open(module_path, 'r', encoding='utf-8') as f:
                    content = f.read()
                processed_count += 1
                
            except UnicodeDecodeError:
                print(f"Encoding error in {module_path}")
                error_count += 1
                
            except PermissionError:
                print(f"Permission denied: {module_path}")
                error_count += 1
                
        print(f"Processed {processed_count} files, {error_count} errors")
        
    except FileNotFoundError as e:
        print(f"Path not found: {e}")
    except Exception as e:
        print(f"Unexpected error during file processing: {e}")

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

Tool Error Handling

from prospector.config import ProspectorConfig
from prospector.run import Prospector
from prospector.exceptions import FatalProspectorException

def run_with_error_tolerance():
    # Configure to continue on tool errors (default behavior)
    config = ProspectorConfig()
    
    # If you want to fail fast on any tool error, set die_on_tool_error
    # This would be done via command line: --die-on-tool-error
    
    prospector = Prospector(config)
    
    try:
        prospector.execute()
        
        messages = prospector.get_messages()
        summary = prospector.get_summary()
        
        # Check if any tools failed
        if summary and "external_config" in summary:
            print(f"External config used: {summary['external_config']}")
        
        # Look for tool failure messages
        tool_failures = [msg for msg in messages if msg.code == "failure"]
        if tool_failures:
            print(f"Warning: {len(tool_failures)} tools failed to run")
            for failure in tool_failures:
                print(f"  {failure.source}: {failure.message}")
        
        return messages
        
    except FatalProspectorException as e:
        print(f"Tool error caused fatal failure: {e.message}")
        raise

messages = run_with_error_tolerance()

Custom Exception Handling

from prospector.exceptions import FatalProspectorException
import logging

class ProspectorRunner:
    def __init__(self):
        self.logger = logging.getLogger(__name__)
    
    def run_analysis(self, config_overrides=None):
        try:
            from prospector.config import ProspectorConfig
            from prospector.run import Prospector
            
            config = ProspectorConfig()
            prospector = Prospector(config)
            prospector.execute()
            
            return {
                'success': True,
                'messages': prospector.get_messages(),
                'summary': prospector.get_summary()
            }
            
        except FatalProspectorException as e:
            self.logger.error(f"Fatal prospector error: {e.message}")
            return {
                'success': False,
                'error': 'fatal',
                'message': e.message
            }
            
        except Exception as e:
            self.logger.exception("Unexpected error during analysis")
            return {
                'success': False,
                'error': 'unexpected',
                'message': str(e)
            }
    
    def handle_result(self, result):
        if result['success']:
            print(f"Analysis successful: {len(result['messages'])} issues")
            return 0
        else:
            print(f"Analysis failed ({result['error']}): {result['message']}")
            return 2 if result['error'] == 'fatal' else 1

# Usage
runner = ProspectorRunner()
result = runner.run_analysis()
exit_code = runner.handle_result(result)

Exception Context and Debugging

from prospector.config import ProspectorConfig
from prospector.run import Prospector
from prospector.exceptions import FatalProspectorException
import traceback

def debug_prospector_error():
    try:
        config = ProspectorConfig()
        prospector = Prospector(config)
        prospector.execute()
        
    except FatalProspectorException as e:
        print("=== FATAL PROSPECTOR ERROR ===")
        print(f"Error message: {e.message}")
        print(f"Error type: {type(e).__name__}")
        
        # Print full traceback for debugging
        print("\nFull traceback:")
        traceback.print_exc()
        
        # Additional debug information
        print(f"\nConfiguration summary:")
        print(f"  Tools to run: {config.tools_to_run}")
        print(f"  Paths: {config.paths}")
        print(f"  Working directory: {config.workdir}")
        
    except Exception as e:
        print("=== UNEXPECTED ERROR ===")
        print(f"Error: {e}")
        print(f"Type: {type(e).__name__}")
        traceback.print_exc()

debug_prospector_error()

Install with Tessl CLI

npx tessl i tessl/pypi-prospector

docs

analysis-runner.md

configuration.md

exceptions.md

file-finding.md

formatters.md

index.md

messages.md

profiles.md

tools.md

tile.json