fix(cors): add API domain to CORS origins and improve instance error handling
- Add API base URL to CORS allowed origins alongside web base URL - Add CORS origin logging on startup for debugging - Wrap instance creation in try/except with detailed error logging - Return proper error message instead of raw 500 for instance creation failures This fixes CORS errors when the frontend makes cross-origin requests and provides better diagnostics for instance creation failures.
This commit is contained in:
@@ -124,53 +124,60 @@ async def create_instance(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="tool type not found"
|
||||
)
|
||||
|
||||
# Generate unique name
|
||||
instance_name = f"{tool_type.name}-{repo.name}-{uuid.uuid4().hex[:8]}"
|
||||
instance_display = data.display_name or f"{tool_type.display_name} - {repo.name}"
|
||||
try:
|
||||
# Generate unique name
|
||||
instance_name = f"{tool_type.name}-{repo.name}-{uuid.uuid4().hex[:8]}"
|
||||
instance_display = data.display_name or f"{tool_type.display_name} - {repo.name}"
|
||||
|
||||
# Create instance directory
|
||||
instance_dir = ensure_instance_directory(instance_name)
|
||||
compose_path = os.path.join(instance_dir, "docker-compose.yml")
|
||||
# Create instance directory
|
||||
instance_dir = ensure_instance_directory(instance_name)
|
||||
compose_path = os.path.join(instance_dir, "docker-compose.yml")
|
||||
|
||||
# Find free port
|
||||
tool_port = find_free_port()
|
||||
# Find free port
|
||||
tool_port = find_free_port()
|
||||
|
||||
# Render compose template
|
||||
variables = {
|
||||
"REPO_PATH": repo.path,
|
||||
"INSTANCE_NAME": instance_name,
|
||||
"INSTANCE_ID": instance_name,
|
||||
"TOOL_PORT": tool_port,
|
||||
"USER_ID": str(user_id),
|
||||
"PROJECT_ID": str(project_id),
|
||||
}
|
||||
compose_content = render_compose_template(tool_type.compose_template, variables)
|
||||
write_compose_file(instance_dir, compose_content)
|
||||
# Render compose template
|
||||
variables = {
|
||||
"REPO_PATH": repo.path,
|
||||
"INSTANCE_NAME": instance_name,
|
||||
"INSTANCE_ID": instance_name,
|
||||
"TOOL_PORT": tool_port,
|
||||
"USER_ID": str(user_id),
|
||||
"PROJECT_ID": str(project_id),
|
||||
}
|
||||
compose_content = render_compose_template(tool_type.compose_template, variables)
|
||||
write_compose_file(instance_dir, compose_content)
|
||||
|
||||
# Create database record
|
||||
instance = ToolInstance(
|
||||
name=instance_name,
|
||||
display_name=instance_display,
|
||||
tool_type_id=tool_type_id,
|
||||
repository_id=repo_id,
|
||||
project_id=project_id,
|
||||
owner_id=user_id,
|
||||
status="pending",
|
||||
compose_path=compose_path,
|
||||
port=tool_port,
|
||||
)
|
||||
session.add(instance)
|
||||
await session.commit()
|
||||
await session.refresh(instance)
|
||||
# Create database record
|
||||
instance = ToolInstance(
|
||||
name=instance_name,
|
||||
display_name=instance_display,
|
||||
tool_type_id=tool_type_id,
|
||||
repository_id=repo_id,
|
||||
project_id=project_id,
|
||||
owner_id=user_id,
|
||||
status="pending",
|
||||
compose_path=compose_path,
|
||||
port=tool_port,
|
||||
)
|
||||
session.add(instance)
|
||||
await session.commit()
|
||||
await session.refresh(instance)
|
||||
|
||||
return {
|
||||
"id": str(instance.id),
|
||||
"name": instance.name,
|
||||
"display_name": instance.display_name,
|
||||
"tool_type_id": str(instance.tool_type_id),
|
||||
"status": instance.status,
|
||||
"created_at": instance.created_at.isoformat(),
|
||||
}
|
||||
return {
|
||||
"id": str(instance.id),
|
||||
"name": instance.name,
|
||||
"display_name": instance.display_name,
|
||||
"tool_type_id": str(instance.tool_type_id),
|
||||
"status": instance.status,
|
||||
"created_at": instance.created_at.isoformat(),
|
||||
}
|
||||
except Exception as exc:
|
||||
logger.exception("Failed to create instance: %s", exc)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Failed to create instance: {exc}",
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
|
||||
@@ -38,9 +38,15 @@ settings = Settings()
|
||||
app = FastAPI(title="Headquarter API")
|
||||
|
||||
# Configure CORS - must be before other middleware
|
||||
# Build allowed origins list including web and api domains
|
||||
cors_origins = [settings.web_base_url]
|
||||
if settings.api_base_url != settings.web_base_url:
|
||||
cors_origins.append(settings.api_base_url)
|
||||
logger.info("CORS configured with origins: %s", cors_origins)
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=[settings.web_base_url],
|
||||
allow_origins=cors_origins,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
|
||||
Reference in New Issue
Block a user