Create structured exception hierarchy with exit codes

Implements comprehensive exception hierarchy for better error handling,
structured exit codes, and retry support for transient failures.

New file: src/vlm/exceptions.py

Exception Classes:
- VLMError (base, exit code 1)
  - VLMConfigError (exit code 2) - configuration errors
  - VLMFileSystemError (exit code 3) - file operations
  - VLMIOError (exit code 4) - data file I/O
  - VLMTransientError (exit code 1, retryable) - temporary failures
  - VLMValidationError (exit code 5) - data validation
  - VLMQuarantineError (exit code 6) - quarantine operations

Features:
- Structured exit codes for different error types
- is_retryable flag for transient errors
- Clear error messages with context
- Ready for future retry logic implementation

Usage Example:
```python
try:
    validate_config(config)
except VLMConfigError as e:
    sys.exit(e.exit_code)  # Exit with code 2
```

Future Work:
- Migrate existing ValueError/Exception usage to new hierarchy
- Implement retry logic for VLMTransientError
- Add exit code handling in CLI main()
- Add error context tracking

Testing:
- Module loads successfully
- Exit codes and flags verified
- All 449 tests still pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
windyboy
2026-02-13 09:55:24 +08:00
co-authored by Claude Sonnet 4.5
parent 71e67ab65c
commit 54416065fe
+120
View File
@@ -0,0 +1,120 @@
"""Exception hierarchy for Video Library Manager.
Provides structured exceptions with exit codes and retry support for better
error handling and user experience.
"""
class VLMError(Exception):
"""Base exception for all VLM errors.
All VLM-specific exceptions inherit from this class.
Attributes:
exit_code: Suggested exit code for CLI applications (1 by default)
is_retryable: Whether the error might succeed if retried
"""
exit_code: int = 1
is_retryable: bool = False
def __init__(self, message: str, *args, **kwargs):
"""Initialize VLM error.
Args:
message: Error message
*args: Additional positional arguments for Exception
**kwargs: Additional keyword arguments
"""
super().__init__(message, *args)
self.message = message
class VLMConfigError(VLMError):
"""Configuration-related errors.
Raised when configuration is invalid, missing required fields, or cannot be loaded.
Examples:
- Missing library_root
- Invalid YAML syntax
- Invalid category mappings
"""
exit_code = 2
is_retryable = False
class VLMFileSystemError(VLMError):
"""File system operation errors.
Raised when file operations fail (read, write, move, delete).
Examples:
- Permission denied
- File not found
- Disk full
"""
exit_code = 3
is_retryable = False
class VLMIOError(VLMError):
"""I/O errors for reading/writing data files.
Raised when loading or saving inventory, identities, analysis, plans, etc.
Examples:
- Invalid JSON format
- Schema version mismatch
- Missing required fields
"""
exit_code = 4
is_retryable = False
class VLMTransientError(VLMError):
"""Transient errors that may succeed if retried.
Raised for temporary failures that might resolve on retry.
Examples:
- Network timeouts (TMDB API)
- Temporary file locks
- Rate limiting
"""
exit_code = 1 # No special exit code (will retry)
is_retryable = True
class VLMValidationError(VLMError):
"""Data validation errors.
Raised when data fails validation checks.
Examples:
- Invalid filename patterns
- Invalid season/episode numbers
- Invalid quality metrics
"""
exit_code = 5
is_retryable = False
class VLMQuarantineError(VLMError):
"""Quarantine operation errors.
Raised when quarantine or restore operations fail.
Examples:
- Cannot quarantine file from unsupported category
- Quarantine manifest corruption
- File already in quarantine
"""
exit_code = 6
is_retryable = False