diff --git a/agenta-backend/agenta_backend/routers/container_router.py b/agenta-backend/agenta_backend/routers/container_router.py index 77fed296bf..199ca3fd3c 100644 --- a/agenta-backend/agenta_backend/routers/container_router.py +++ b/agenta-backend/agenta_backend/routers/container_router.py @@ -158,52 +158,54 @@ async def construct_app_container_url( Raises: HTTPException: If the base or variant cannot be found or the user does not have access. """ - # assert that one of base_id or variant_id is provided - assert base_id or variant_id, "Please provide either base_id or variant_id" - - if base_id: - object_db = await db_manager.fetch_base_by_id(base_id) - elif variant_id and variant_id != "None": - # NOTE: Backward Compatibility - # --------------------------- - # When a user creates a human evaluation with a variant and later deletes the variant, - # the human evaluation page becomes inaccessible due to the backend raising a - # "'NoneType' object has no attribute 'variant_id'" error. To suppress this error, - # we will return the string "None" as the ID of the variant. - # This change ensures that users can still view their evaluations; however, - # they will no longer be able to access a deployment URL for the deleted variant. - # Therefore, we ensure that variant_id is not "None". - object_db = await db_manager.fetch_app_variant_by_id(variant_id) - else: - # NOTE: required for backward compatibility - object_db = None - - # Check app access - if isCloudEE() and object_db is not None: - has_permission = await check_action_access( - user_uid=request.state.user_id, - project_id=str(object_db.project_id), - permission=Permission.VIEW_APPLICATION, - ) - if not has_permission: - error_msg = f"You do not have permission to perform this action. Please contact your organization admin." - logger.error(error_msg) - raise HTTPException(status_code=403, detail=error_msg) try: - if getattr(object_db, "deployment_id", None): # this is a base - deployment = await db_manager.get_deployment_by_id( - str(object_db.deployment_id) # type: ignore - ) - elif getattr(object_db, "base_id", None): # this is a variant - deployment = await db_manager.get_deployment_by_id( - str(object_db.base.deployment_id) # type: ignore - ) + # assert that one of base_id or variant_id is provided + assert base_id or variant_id, "Please provide either base_id or variant_id" + + if base_id: + object_db = await db_manager.fetch_base_by_id(base_id) + elif variant_id and variant_id != "None": + # NOTE: Backward Compatibility + # --------------------------- + # When a user creates a human evaluation with a variant and later deletes the variant, + # the human evaluation page becomes inaccessible due to the backend raising a + # "'NoneType' object has no attribute 'variant_id'" error. To suppress this error, + # we will return the string "None" as the ID of the variant. + # This change ensures that users can still view their evaluations; however, + # they will no longer be able to access a deployment URL for the deleted variant. + # Therefore, we ensure that variant_id is not "None". + object_db = await db_manager.fetch_app_variant_by_id(variant_id) else: - raise HTTPException( - status_code=400, - detail="Deployment not found", + # NOTE: required for backward compatibility + object_db = None + + # Check app access + if isCloudEE() and object_db is not None: + has_permission = await check_action_access( + user_uid=request.state.user_id, + project_id=str(object_db.project_id), + permission=Permission.VIEW_APPLICATION, ) - return URI(uri=deployment.uri) + if not has_permission: + error_msg = f"You do not have permission to perform this action. Please contact your organization admin." + logger.error(error_msg) + raise HTTPException(status_code=403, detail=error_msg) + + if getattr(object_db, "deployment_id", None): # this is a base + deployment = await db_manager.get_deployment_by_id( + str(object_db.deployment_id) # type: ignore + ) + elif getattr(object_db, "base_id", None): # this is a variant + deployment = await db_manager.get_deployment_by_id( + str(object_db.base.deployment_id) # type: ignore + ) + else: + raise HTTPException( + status_code=400, + detail="Deployment not found", + ) + return URI(uri=deployment.uri) except Exception as e: - return JSONResponse({"message": str(e)}, status_code=500) + status_code = e.status_code if hasattr(e, "status_code") else 500 + return JSONResponse({"detail": str(e)}, status_code=status_code) diff --git a/agenta-backend/agenta_backend/services/db_manager.py b/agenta-backend/agenta_backend/services/db_manager.py index 6108774a24..2f540e24f9 100644 --- a/agenta-backend/agenta_backend/services/db_manager.py +++ b/agenta-backend/agenta_backend/services/db_manager.py @@ -298,6 +298,8 @@ async def fetch_base_by_id(base_id: str) -> Optional[VariantBaseDB]: .filter_by(id=uuid.UUID(base_uuid)) ) base = result.scalars().first() + if base is None: + raise NoResultFound(f"Base with id {base_id} not found") return base