diff --git a/apps/api/src/api/tool_instances.py b/apps/api/src/api/tool_instances.py index 1d5f9ba..769665a 100644 --- a/apps/api/src/api/tool_instances.py +++ b/apps/api/src/api/tool_instances.py @@ -1,9 +1,12 @@ """Tool instance API endpoints.""" +import logging import os import uuid from datetime import datetime +logger = logging.getLogger(__name__) + from fastapi import APIRouter, Depends, HTTPException, status from pydantic import BaseModel, Field from sqlalchemy import select @@ -33,6 +36,8 @@ router = APIRouter(prefix="/projects", tags=["tool-instances"]) class CreateInstanceRequest(BaseModel): """Request body for creating a tool instance.""" + model_config = {"extra": "ignore"} + tool_type_id: str = Field(description="UUID of the tool type to instantiate") display_name: str | None = Field(default=None, description="Optional display name for the instance") @@ -96,6 +101,13 @@ async def create_instance( Returns: Dictionary with instance details. """ + logger.info( + "Creating instance: project_id=%s, repo_id=%s, tool_type_id=%s, display_name=%s", + project_id, + repo_id, + data.tool_type_id, + data.display_name, + ) _user = await _get_user(session, user_id) _project = await _get_owned_project(project_id, user_id, session) diff --git a/apps/api/src/main.py b/apps/api/src/main.py index f5ca7dc..412b36c 100644 --- a/apps/api/src/main.py +++ b/apps/api/src/main.py @@ -1,8 +1,10 @@ import logging import os -from fastapi import FastAPI +from fastapi import FastAPI, Request +from fastapi.exceptions import RequestValidationError from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import JSONResponse from fastapi.staticfiles import StaticFiles from sqlalchemy import select, text @@ -48,6 +50,22 @@ app.add_middleware(RequestLoggingMiddleware) app.add_middleware(ExceptionLoggingMiddleware) +@app.exception_handler(RequestValidationError) +async def validation_exception_handler(request: Request, exc: RequestValidationError): + """Log validation errors and return detailed response.""" + errors = exc.errors() + logger.warning( + "Validation error for %s %s: %s", + request.method, + request.url.path, + errors, + ) + return JSONResponse( + status_code=422, + content={"detail": errors}, + ) + + async def _table_exists(session, table_name: str) -> bool: """Check if a table exists in the database.""" try: