"""Plugin error isolation wrapper.""" import logging import functools import inspect from fastapi import UploadFile as _UploadFile # noqa: F401 — needed for ForwardRef resolution from fastapi.responses import JSONResponse logger = logging.getLogger(__name__) def wrap_plugin_route(handler): """Decorator that isolates plugin route errors and returns structured JSON. Copies the original handler's signature so FastAPI sees the correct parameters (path params, query params, body, etc.) instead of *args/**kwargs. Avoids copying __annotations__ to prevent ForwardRef('UploadFile') issues. """ @functools.wraps(handler) async def wrapper(*args, **kwargs): try: return await handler(*args, **kwargs) except Exception as exc: logger.error(f'Plugin route error: {exc}', exc_info=True) return JSONResponse( status_code=500, content={'detail': f'Plugin error: {exc}', 'code': 'plugin_error'} ) # Remove annotations that cause ForwardRef resolution issues wrapper.__annotations__ = {} # Remove __wrapped__ so FastAPI doesn't try to resolve the original signature # (which may have ForwardRef('UploadFile') that can't be resolved) if hasattr(wrapper, '__wrapped__'): delattr(wrapper, '__wrapped__') # Copy the signature from the original handler so FastAPI sees correct params try: orig_sig = inspect.signature(handler) wrapper.__signature__ = orig_sig except (ValueError, TypeError): pass return wrapper