fix: auto repair bugs #71 #5

Closed
zyc wants to merge 1 commits from fix/auto-20260318-161048 into main

View File

@ -3,6 +3,7 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from sqlmodel.ext.asyncio.session import AsyncSession from sqlmodel.ext.asyncio.session import AsyncSession
from sqlmodel import select, func, text from sqlmodel import select, func, text
from sqlalchemy.exc import IntegrityError
from .database import init_db, get_session, engine from .database import init_db, get_session, engine
from .models import ErrorLog, ErrorLogCreate, LogStatus, TaskStatusUpdate, RepairTask, RepairTaskCreate, Project, ProjectUpdate from .models import ErrorLog, ErrorLogCreate, LogStatus, TaskStatusUpdate, RepairTask, RepairTaskCreate, Project, ProjectUpdate
from .gitea_client import GiteaClient from .gitea_client import GiteaClient
@ -163,7 +164,39 @@ async def report_log(log_data: ErrorLogCreate, session: AsyncSession = Depends(g
) )
session.add(new_log) session.add(new_log)
await session.commit() try:
await session.commit()
except IntegrityError:
await session.rollback()
# Race condition: another request inserted the same fingerprint concurrently
statement = select(ErrorLog).where(ErrorLog.fingerprint == fingerprint)
results = await session.exec(statement)
existing_log = results.first()
if existing_log:
if existing_log.status not in [LogStatus.DEPLOYED, LogStatus.FIXED, LogStatus.VERIFIED]:
existing_log.error_message = log_data.error.get("message", existing_log.error_message)
existing_log.stack_trace = log_data.error.get("stack_trace", existing_log.stack_trace)
existing_log.context = log_data.context or existing_log.context
existing_log.timestamp = log_data.timestamp or datetime.utcnow()
if log_data.commit_hash:
existing_log.commit_hash = log_data.commit_hash
session.add(existing_log)
await session.commit()
await session.refresh(existing_log)
return {"message": "Log deduplicated (content updated)", "id": existing_log.id, "status": existing_log.status}
existing_log.status = LogStatus.NEW
existing_log.error_message = log_data.error.get("message", existing_log.error_message)
existing_log.stack_trace = log_data.error.get("stack_trace", existing_log.stack_trace)
existing_log.context = log_data.context or existing_log.context
existing_log.timestamp = log_data.timestamp or datetime.utcnow()
existing_log.retry_count = 0
if log_data.commit_hash:
existing_log.commit_hash = log_data.commit_hash
session.add(existing_log)
await session.commit()
await session.refresh(existing_log)
return {"message": "Regression detected, reopened", "id": existing_log.id}
raise
await session.refresh(new_log) await session.refresh(new_log)
return {"message": "Log reported", "id": new_log.id} return {"message": "Log reported", "id": new_log.id}