Return existing asset instead of error when asset already exists
When publishing to L2, if the asset already exists, return it with existing: true flag instead of raising a 400 error. This makes re-publishing idempotent and handles race conditions gracefully. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
19
server.py
19
server.py
@@ -1784,9 +1784,11 @@ async def _register_asset_impl(req: RegisterRequest, owner: str):
|
||||
if not req.ipfs_cid:
|
||||
raise HTTPException(400, "IPFS CID is required for registration")
|
||||
|
||||
# Check if name exists
|
||||
if await db.asset_exists(req.name):
|
||||
raise HTTPException(400, f"Asset already exists: {req.name}")
|
||||
# Check if name exists - return existing asset if so
|
||||
existing = await db.get_asset_by_name(req.name)
|
||||
if existing:
|
||||
logger.info(f"register_asset: Asset {req.name} already exists, returning existing")
|
||||
return {"asset": existing, "activity": None, "existing": True}
|
||||
|
||||
# ===== PHASE 2: IPFS OPERATIONS (non-blocking) =====
|
||||
import asyncio
|
||||
@@ -1805,7 +1807,10 @@ async def _register_asset_impl(req: RegisterRequest, owner: str):
|
||||
async with db.transaction() as conn:
|
||||
# Check name again inside transaction (race condition protection)
|
||||
if await db.asset_exists_by_name_tx(conn, req.name):
|
||||
raise HTTPException(400, f"Asset already exists: {req.name}")
|
||||
# Race condition - another request created it first, return existing
|
||||
existing = await db.get_asset_by_name(req.name)
|
||||
logger.info(f"register_asset: Asset {req.name} created by concurrent request")
|
||||
return {"asset": existing, "activity": None, "existing": True}
|
||||
|
||||
# Create asset
|
||||
asset = {
|
||||
@@ -2084,9 +2089,11 @@ async def record_run(req: RecordRunRequest, user: User = Depends(get_required_us
|
||||
}
|
||||
await db.create_asset_tx(conn, input_asset)
|
||||
|
||||
# Check output doesn't already exist (by content_hash)
|
||||
# Check if output already exists (by content_hash) - return existing if so
|
||||
if await db.asset_exists_by_name_tx(conn, output_hash):
|
||||
raise HTTPException(400, f"Asset already exists: {output_hash[:16]}...")
|
||||
existing = await db.get_asset_by_name(output_hash)
|
||||
logger.info(f"record_run: Output {output_hash[:16]}... already exists")
|
||||
return {"asset": existing, "activity": None, "existing": True}
|
||||
|
||||
# Create output asset with provenance - named by content_hash
|
||||
output_asset = {
|
||||
|
||||
Reference in New Issue
Block a user