CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-rope

A comprehensive Python refactoring library providing powerful and safe code transformations, analysis, and IDE integration capabilities.

Pending
Overview
Eval results
Files

error-handling.mddocs/

Error Handling

Exception hierarchy for handling various error conditions during code analysis and refactoring operations. Rope provides specific exception types for different failure scenarios to enable appropriate error handling and user feedback.

Exception Hierarchy

All rope exceptions inherit from the base RopeError class, providing a consistent error handling interface.

class RopeError(Exception):
    """
    Base exception class for all rope errors.
    All rope-specific exceptions inherit from this class.
    """
    pass

Capabilities

Refactoring Errors

Errors that occur during refactoring operations due to code structure or safety constraints.

class RefactoringError(RopeError):
    """
    General refactoring error for operations that cannot be completed safely.
    Raised when a refactoring violates safety constraints or encounters
    unsupported code patterns.
    """
    pass

class InterruptedTaskError(RopeError):
    """
    Raised when a refactoring task is cancelled or interrupted.
    Can occur when using TaskHandle to monitor long-running operations.
    """
    pass

Resource Errors

Errors related to file system operations and resource management.

class ResourceNotFoundError(RopeError):
    """
    Raised when attempting to access a resource that doesn't exist.
    Common when using project.get_resource() with invalid paths.
    """
    pass

Module and Import Errors

Errors related to Python module loading and import resolution.

class ModuleNotFoundError(RopeError):
    """
    Raised when a Python module cannot be found or loaded.
    Occurs during module resolution in project.get_module() operations.
    """
    pass

class AttributeNotFoundError(RopeError):
    """
    Raised when attempting to access a non-existent attribute.
    Can occur during code analysis and refactoring operations.
    """
    pass

class NameNotFoundError(RopeError):
    """
    Raised when name resolution fails during code analysis.
    Indicates that a referenced identifier cannot be resolved.
    """
    pass

Syntax and Validation Errors

Errors related to code syntax and identifier validation.

class BadIdentifierError(RopeError):
    """
    Raised when an invalid identifier is provided for refactoring.
    Common in rename operations with non-Python identifiers.
    """
    pass

class ModuleSyntaxError(RopeError):
    """
    Raised when a Python module contains syntax errors.
    Can occur during parsing and analysis operations.
    """
    pass

class ModuleDecodeError(RopeError):
    """
    Raised when a Python file cannot be decoded due to encoding issues.
    Occurs when reading files with invalid or unsupported encodings.
    """
    pass

History and State Errors

Errors related to project history and state management.

class HistoryError(RopeError):
    """
    Raised when history operations fail.
    Can occur during undo/redo operations or history corruption.
    """
    pass

Error Handling Patterns

Basic Exception Handling

from rope.base.project import Project
from rope.base.exceptions import RopeError, ResourceNotFoundError, RefactoringError
from rope.refactor.rename import Rename

project = Project('/path/to/project')

try:
    # Attempt to get a resource
    try:
        myfile = project.get_resource('nonexistent.py')
    except ResourceNotFoundError:
        print("File not found, creating new file")
        myfile = project.get_file('nonexistent.py')
        myfile.write('# New file\n')
    
    # Attempt refactoring with error handling
    try:
        renamer = Rename(project, myfile, 50)
        old_name = renamer.get_old_name()
        changes = renamer.get_changes('new_name')
        project.do(changes)
        print(f"Successfully renamed '{old_name}' to 'new_name'")
        
    except RefactoringError as e:
        print(f"Refactoring failed: {e}")
        # Handle refactoring-specific errors
        
    except BadIdentifierError as e:
        print(f"Invalid identifier: {e}")
        # Handle identifier validation errors
        
except RopeError as e:
    print(f"Rope error occurred: {e}")
    # Handle any rope-specific error
    
except Exception as e:
    print(f"Unexpected error: {e}")
    # Handle unexpected errors
    
finally:
    project.close()

Module Loading Error Handling

from rope.base.project import Project
from rope.base.exceptions import ModuleNotFoundError, ModuleSyntaxError, ModuleDecodeError

project = Project('/path/to/project')

try:
    # Handle various module loading errors
    try:
        module = project.get_module('mymodule')
        print(f"Module loaded: {module}")
        
    except ModuleNotFoundError:
        print("Module not found in project or Python path")
        # Try alternative module names or create module
        
    except ModuleSyntaxError as e:
        print(f"Module has syntax errors: {e}")
        # Report syntax issues to user
        
    except ModuleDecodeError as e:
        print(f"Cannot decode module file: {e}")
        # Handle encoding issues
        
finally:
    project.close()

Task Interruption Handling

from rope.base.project import Project
from rope.base.taskhandle import TaskHandle
from rope.base.exceptions import InterruptedTaskError
from rope.refactor.rename import Rename

def cancel_callback():
    # Custom cancellation logic
    return user_requested_cancel()

project = Project('/path/to/project')

try:
    # Create task handle with cancellation support
    task_handle = TaskHandle("Rename operation", cancel_callback)
    
    try:
        myfile = project.get_resource('mymodule.py')
        renamer = Rename(project, myfile, 100)
        changes = renamer.get_changes('new_name', task_handle=task_handle)
        project.do(changes, task_handle)
        print("Refactoring completed successfully")
        
    except InterruptedTaskError:
        print("Operation was cancelled by user")
        # Clean up partial changes if necessary
        
finally:
    project.close()

Comprehensive Error Handling

from rope.base.project import Project
from rope.base.exceptions import *
from rope.refactor.extract import ExtractMethod

def safe_refactor(project_path, file_path, start_offset, end_offset, method_name):
    """
    Safely perform extract method refactoring with comprehensive error handling.
    """
    project = None
    try:
        project = Project(project_path)
        
        # Resource access with error handling
        try:
            resource = project.get_resource(file_path)
        except ResourceNotFoundError:
            return {"error": f"File not found: {file_path}"}
        
        # Refactoring with error handling
        try:
            extractor = ExtractMethod(project, resource, start_offset, end_offset)
            changes = extractor.get_changes(method_name)
            
            # Validate changes before applying
            description = changes.get_description()
            print(f"About to apply: {description}")
            
            project.do(changes)
            return {"success": f"Extracted method '{method_name}'"}
            
        except RefactoringError as e:
            return {"error": f"Refactoring failed: {e}"}
            
        except BadIdentifierError as e:
            return {"error": f"Invalid method name '{method_name}': {e}"}
            
        except InterruptedTaskError:
            return {"error": "Operation was cancelled"}
            
        except ModuleSyntaxError as e:
            return {"error": f"Syntax error in file: {e}"}
            
    except RopeError as e:
        return {"error": f"Rope error: {e}"}
        
    except Exception as e:
        return {"error": f"Unexpected error: {e}"}
        
    finally:
        if project:
            project.close()

# Usage
result = safe_refactor(
    "/path/to/project",
    "mymodule.py", 
    200, 350,
    "extracted_method"
)

if "error" in result:
    print(f"Error: {result['error']}")
else:
    print(f"Success: {result['success']}")

Error Recovery Patterns

from rope.base.project import Project
from rope.base.exceptions import *

def robust_rename(project_path, file_path, offset, new_name, max_retries=3):
    """
    Perform rename with automatic retry and error recovery.
    """
    project = Project(project_path)
    
    try:
        resource = project.get_resource(file_path)
        
        for attempt in range(max_retries + 1):
            try:
                from rope.refactor.rename import Rename
                renamer = Rename(project, resource, offset)
                
                # Validate before proceeding
                try:
                    old_name = renamer.get_old_name()
                    print(f"Attempt {attempt + 1}: Renaming '{old_name}' to '{new_name}'")
                except AttributeNotFoundError:
                    print("No identifier found at offset")
                    return False
                
                changes = renamer.get_changes(new_name)
                project.do(changes)
                print("Rename successful")
                return True
                
            except BadIdentifierError as e:
                print(f"Invalid identifier on attempt {attempt + 1}: {e}")
                if attempt == max_retries:
                    print("All attempts failed - invalid identifier")
                    return False
                # Could try with modified identifier
                
            except RefactoringError as e:
                print(f"Refactoring error on attempt {attempt + 1}: {e}")
                if attempt == max_retries:
                    print("All attempts failed - refactoring error")
                    return False
                # Could try with different parameters
                
            except InterruptedTaskError:
                print("Operation cancelled")
                return False
                
    except ResourceNotFoundError:
        print(f"File not found: {file_path}")
        return False
        
    finally:
        project.close()
    
    return False

Best Practices

Exception Handling Guidelines

  1. Catch Specific Exceptions: Always catch the most specific exception type first
  2. Resource Cleanup: Use try/finally or context managers to ensure projects are closed
  3. User Feedback: Provide meaningful error messages for different exception types
  4. Graceful Degradation: Handle errors gracefully and provide fallback options
  5. Logging: Log errors with sufficient context for debugging

Common Error Scenarios

  • ResourceNotFoundError: Check file existence before operations
  • RefactoringError: Validate code structure before complex refactorings
  • BadIdentifierError: Validate identifier names before rename operations
  • ModuleSyntaxError: Parse and validate syntax before analysis
  • InterruptedTaskError: Handle user cancellation in long operations

Install with Tessl CLI

npx tessl i tessl/pypi-rope

docs

change-management.md

code-assistance.md

error-handling.md

index.md

project-management.md

refactoring-operations.md

tile.json