## Summary
- Reorganizes `django/aiservice/` from feature-first layout (separate
`optimizer/`, `testgen/`, `code_repair/` dirs) to language-first layout
under `core/languages/{python,js_ts}/`
- Adds handler/registry/dispatcher pattern for routing requests to
language-specific implementations
- All existing module code preserved via `git mv` for history tracking;
no logic changes to existing modules
## What changed
- New `core/` app with registry, dispatcher, protocols, and error
hierarchy
- `PythonHandler` and `JSTypeScriptHandler` delegate to existing module
functions
- All imports updated across the codebase (views, tests,
adaptive_optimizer, etc.)
- Integration tests for handler registration and dispatch
- 155 files changed, ~880 additions / ~207 deletions (mostly import path
updates and moves)
## Test plan
- [ ] `python manage.py check` passes
- [ ] Integration tests in
`tests/integration/test_handler_integration.py` pass
- [ ] Existing test suite passes with updated import paths
- [ ] Ruff and ty clean on all new infrastructure files
---------
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
50 lines
2 KiB
Python
50 lines
2 KiB
Python
"""Error hierarchy for language handler system."""
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
class HandlerError(Exception):
|
|
"""Base error for handler system."""
|
|
|
|
def __init__(self, message: str, context: dict[str, object] | None = None) -> None:
|
|
super().__init__(message)
|
|
self.context = context or {}
|
|
|
|
|
|
class LanguageNotFoundError(HandlerError):
|
|
"""Raised when no handler is registered for the requested language."""
|
|
|
|
def __init__(self, language_id: str, available: list[str]) -> None:
|
|
available_str = ", ".join(available) if available else "none"
|
|
message = f"Language handler for '{language_id}' not found. Available: {available_str}"
|
|
super().__init__(message, {"language_id": language_id, "available": available})
|
|
|
|
|
|
class HandlerNotImplementedError(HandlerError):
|
|
"""Raised when a handler doesn't support the requested feature."""
|
|
|
|
def __init__(self, language_id: str, feature: str, capability: str) -> None:
|
|
message = (
|
|
f"Handler for '{language_id}' does not support {feature} capability '{capability}'. "
|
|
f"Check handler.capabilities['{feature}']."
|
|
)
|
|
super().__init__(message, {"language_id": language_id, "feature": feature, "capability": capability})
|
|
|
|
|
|
class PipelineError(HandlerError):
|
|
"""Raised when a pipeline stage fails."""
|
|
|
|
def __init__(self, stage: str, message: str, cause: Exception | None = None) -> None:
|
|
full_message = f"Pipeline error in {stage}: {message}"
|
|
if cause:
|
|
full_message += f" (caused by {type(cause).__name__}: {cause!s})"
|
|
super().__init__(full_message, {"stage": stage, "cause": cause})
|
|
self.__cause__ = cause
|
|
|
|
|
|
class ValidationError(HandlerError):
|
|
"""Raised when input validation fails."""
|
|
|
|
def __init__(self, field: str, message: str, value: object = None) -> None:
|
|
full_message = f"Validation failed for '{field}': {message}"
|
|
super().__init__(full_message, {"field": field, "value": value})
|