"""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. Removes return annotation to prevent ForwardRef('UploadFile') resolution 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 if hasattr(wrapper, '__wrapped__'): delattr(wrapper, '__wrapped__') # Copy the signature from the original handler but remove return annotation try: orig_sig = inspect.signature(handler) # Create new signature without return annotation new_params = list(orig_sig.parameters.values()) wrapper.__signature__ = orig_sig.replace( parameters=new_params, return_annotation=inspect.Signature.empty, ) except (ValueError, TypeError): pass return wrapper