refactor: Standardize error handling patterns across codebase
Comprehensive error handling improvements addressing inconsistent patterns: • Created markitect/exceptions.py with complete domain-specific exception hierarchy - MarkitectError base class with context and cause chaining support - Specific exceptions for Document, AST, Cache, Database, Schema operations - Built-in logging and context preservation • Fixed overly broad exception handling in tddai modules: - issue_fetcher.py: Replace generic Exception with specific Gitea errors - project_manager.py: Proper error translation with context preservation - coverage_analyzer.py: Replace silent suppression with logging • Enhanced cache_service.py error handling: - Specific OSError/PermissionError handling for file operations - Logging integration for unexpected errors - Preserved error collection and reporting • Implemented proper exception chaining patterns: - All error translations use `raise ... from e` for debugging - Preserved original exception context and stack traces - Added docstring declarations of raised exceptions • Benefits: - Eliminates silent error suppression and debugging black holes - Provides specific, actionable error messages - Preserves full error context for troubleshooting - Establishes consistent patterns for future development Resolves issue #21: Error handling standardization 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ maintaining backwards compatibility while using the cleaner API.
|
||||
from typing import List, Dict, Any
|
||||
|
||||
from gitea import GiteaClient, Issue as GiteaIssue, GiteaConfig
|
||||
from gitea.exceptions import GiteaError, GiteaNotFoundError, GiteaAuthError, GiteaApiError
|
||||
from .config import get_config
|
||||
from .exceptions import IssueError
|
||||
|
||||
@@ -26,27 +27,54 @@ class IssueFetcher:
|
||||
self.gitea_client = GiteaClient(gitea_config)
|
||||
|
||||
def fetch_issue(self, issue_number: int) -> Issue:
|
||||
"""Fetch a specific issue by number."""
|
||||
"""Fetch a specific issue by number.
|
||||
|
||||
Raises:
|
||||
IssueError: When issue cannot be fetched (with specific context)
|
||||
"""
|
||||
try:
|
||||
return self.gitea_client.issues.get(issue_number)
|
||||
except Exception as e:
|
||||
# Convert gitea exceptions to IssueError for backwards compatibility
|
||||
raise IssueError(f"Failed to fetch issue #{issue_number}: {e}")
|
||||
except GiteaNotFoundError as e:
|
||||
raise IssueError(f"Issue #{issue_number} not found") from e
|
||||
except GiteaAuthError as e:
|
||||
raise IssueError(f"Authentication failed when fetching issue #{issue_number}") from e
|
||||
except GiteaApiError as e:
|
||||
raise IssueError(f"API error fetching issue #{issue_number}: {e}") from e
|
||||
except GiteaError as e:
|
||||
raise IssueError(f"Gitea error fetching issue #{issue_number}: {e}") from e
|
||||
|
||||
def fetch_issues(self, state: str = "all") -> List[Issue]:
|
||||
"""Fetch all issues with optional state filter."""
|
||||
"""Fetch all issues with optional state filter.
|
||||
|
||||
Args:
|
||||
state: Issue state filter ("all", "open", "closed")
|
||||
|
||||
Raises:
|
||||
IssueError: When issues cannot be fetched (with specific context)
|
||||
"""
|
||||
try:
|
||||
return self.gitea_client.issues.list(state=state)
|
||||
except Exception as e:
|
||||
# Convert gitea exceptions to IssueError for backwards compatibility
|
||||
raise IssueError(f"Failed to fetch issues: {e}")
|
||||
except GiteaAuthError as e:
|
||||
raise IssueError("Authentication failed when fetching issues") from e
|
||||
except GiteaApiError as e:
|
||||
raise IssueError(f"API error fetching issues with state '{state}': {e}") from e
|
||||
except GiteaError as e:
|
||||
raise IssueError(f"Gitea error fetching issues: {e}") from e
|
||||
|
||||
def fetch_open_issues(self) -> List[Issue]:
|
||||
"""Fetch only open issues."""
|
||||
"""Fetch only open issues.
|
||||
|
||||
Raises:
|
||||
IssueError: When open issues cannot be fetched (with specific context)
|
||||
"""
|
||||
try:
|
||||
return self.gitea_client.issues.list_open()
|
||||
except Exception as e:
|
||||
raise IssueError(f"Failed to fetch open issues: {e}")
|
||||
except GiteaAuthError as e:
|
||||
raise IssueError("Authentication failed when fetching open issues") from e
|
||||
except GiteaApiError as e:
|
||||
raise IssueError(f"API error fetching open issues: {e}") from e
|
||||
except GiteaError as e:
|
||||
raise IssueError(f"Gitea error fetching open issues: {e}") from e
|
||||
|
||||
def get_issue_data_dict(self, issue_number: int) -> Dict[str, Any]:
|
||||
"""Get issue data as dictionary for workspace creation."""
|
||||
|
||||
Reference in New Issue
Block a user