Centralize best-effort deletes: log errors and continue review flow.

All cleanup deletes now use runBestEffort so Gitea delete failures never abort posting the new review.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Daan Schouteden
2026-06-03 13:29:40 +02:00
parent 8bcd91cdb2
commit 95fa696935
4 changed files with 54 additions and 37 deletions
+8 -1
View File
@@ -1,4 +1,5 @@
import { GiteaClient } from "./client.js";
import { runBestEffort } from "./run-best-effort.js";
export const PROGRESS_COMMENT_MARKER = "<!-- gitea-pr-review-bot-progress -->";
@@ -26,8 +27,14 @@ export async function deleteProgressComment(input: {
owner: string;
repo: string;
commentId: number;
correlationId?: string;
}): Promise<void> {
await input.gitea.deleteIssueComment(input.owner, input.repo, input.commentId);
await runBestEffort({
operation: "Delete progress comment",
correlationId: input.correlationId,
context: { comment_id: input.commentId },
fn: () => input.gitea.deleteIssueComment(input.owner, input.repo, input.commentId)
});
}
export const TIMEOUT_FAILURE_MARKER = "<!-- gitea-pr-review-bot-timeout -->";
+12 -17
View File
@@ -1,8 +1,7 @@
import { log } from "../logging/logger.js";
import { GiteaClient, PullFile } from "./client.js";
import { ReviewResult } from "../cursor/review-schema.js";
import { runBestEffort } from "./run-best-effort.js";
/** Best-effort cleanup; never throws (Gitea may return 500 for some review states). */
export async function deletePriorBotReviews(input: {
gitea: GiteaClient;
owner: string;
@@ -11,30 +10,26 @@ export async function deletePriorBotReviews(input: {
botLogin: string;
correlationId?: string;
}): Promise<void> {
try {
await runBestEffort({
operation: "List prior bot reviews",
correlationId: input.correlationId,
context: { pr_number: input.prNumber },
fn: async () => {
const reviews = await input.gitea.getReviews(input.owner, input.repo, input.prNumber);
const botReviews = reviews.filter((review) => review.user?.login === input.botLogin);
for (const review of botReviews) {
try {
await input.gitea.deleteReview(input.owner, input.repo, input.prNumber, review.id);
} catch (error) {
log("warn", "Failed to delete prior bot review (continuing)", {
correlation_id: input.correlationId,
review_id: review.id,
pr_number: input.prNumber,
error: error instanceof Error ? error.message : String(error)
await runBestEffort({
operation: "Delete prior bot review",
correlationId: input.correlationId,
context: { review_id: review.id, pr_number: input.prNumber },
fn: () =>
input.gitea.deleteReview(input.owner, input.repo, input.prNumber, review.id)
});
}
}
} catch (error) {
log("warn", "Failed to list prior bot reviews for cleanup (continuing)", {
correlation_id: input.correlationId,
pr_number: input.prNumber,
error: error instanceof Error ? error.message : String(error)
});
}
}
export async function postReview(input: {
gitea: GiteaClient;
+23
View File
@@ -0,0 +1,23 @@
import { log } from "../logging/logger.js";
/** Run a cleanup step; log failures and continue the review flow. */
export async function runBestEffort(input: {
operation: string;
correlationId?: string;
context?: Record<string, unknown>;
fn: () => Promise<void>;
}): Promise<void> {
try {
await input.fn();
log("info", `${input.operation} succeeded`, {
correlation_id: input.correlationId,
...input.context
});
} catch (error) {
log("warn", `${input.operation} failed (continuing)`, {
correlation_id: input.correlationId,
...input.context,
error: error instanceof Error ? error.message : String(error)
});
}
}
+6 -14
View File
@@ -234,21 +234,13 @@ async function executeReview(params: {
throw error;
} finally {
if (progressCommentId !== undefined) {
try {
await deleteProgressComment({ gitea, owner, repo, commentId: progressCommentId });
log("info", "Removed progress comment from PR", {
correlation_id: input.correlationId,
pr_number: prNumber,
comment_id: progressCommentId
await deleteProgressComment({
gitea,
owner,
repo,
commentId: progressCommentId,
correlationId: input.correlationId
});
} catch (error) {
log("warn", "Failed to remove progress comment from PR", {
correlation_id: input.correlationId,
pr_number: prNumber,
comment_id: progressCommentId,
error: error instanceof Error ? error.message : String(error)
});
}
}
}
}