From df8011d7c071c9936970bddc09834cc678b4262d Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Sat, 14 Mar 2026 07:15:08 +0000 Subject: [PATCH 1/2] [#55] Fix cron backfill silently swallowing database errors All upsert calls now destructure { error } and throw on failure, so DB errors are caught by the existing try/catch and counted in the errors response field. Cursor update also checks for errors. Removed 3 unused imports (plotChainedEvent, storylineCreatedEvent, donationEvent). Fixes #55 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/api/cron/backfill/route.ts | 32 ++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/app/api/cron/backfill/route.ts b/src/app/api/cron/backfill/route.ts index 4a3a2b32..f6c540ec 100644 --- a/src/app/api/cron/backfill/route.ts +++ b/src/app/api/cron/backfill/route.ts @@ -2,12 +2,7 @@ import { NextResponse } from "next/server"; import { decodeEventLog, type Log } from "viem"; import { publicClient } from "../../../../../lib/viem"; import { createServerClient } from "../../../../../lib/supabase"; -import { - storyFactoryAbi, - plotChainedEvent, - storylineCreatedEvent, - donationEvent, -} from "../../../../../lib/contracts/abi"; +import { storyFactoryAbi } from "../../../../../lib/contracts/abi"; import { STORY_FACTORY } from "../../../../../lib/contracts/constants"; import { hashContent } from "../../../../../lib/content"; import { detectWriterType } from "../../../../../lib/contracts/erc8004"; @@ -165,9 +160,12 @@ export async function GET(req: Request) { // Persist cursor — advance to highest block actually scanned // eslint-disable-next-line @typescript-eslint/no-explicit-any - await (supabase.from("backfill_cursor") as any) + const { error: cursorError } = await (supabase.from("backfill_cursor") as any) .update({ last_block: Number(toBlock), updated_at: new Date().toISOString() }) .eq("id", 1); + if (cursorError) { + console.error(`Failed to update backfill cursor: ${cursorError.message}`); + } return NextResponse.json({ scanned: { fromBlock: Number(fromBlock), toBlock: Number(toBlock) }, @@ -220,9 +218,12 @@ async function processStorylineCreated( log_index: logIndex, }; - await supabase + const { error: storylineError } = await supabase .from("storylines") .upsert(storylineRow, { onConflict: "tx_hash,log_index" }); + if (storylineError) { + throw new Error(`Database error (storyline): ${storylineError.message}`); + } // Insert genesis plot const content = await fetchIPFSContent(openingCID); @@ -238,9 +239,12 @@ async function processStorylineCreated( tx_hash: txHash, log_index: logIndex, }; - await supabase + const { error: plotError } = await supabase .from("plots") .upsert(plotRow, { onConflict: "tx_hash,log_index" }); + if (plotError) { + throw new Error(`Database error (genesis plot): ${plotError.message}`); + } } } @@ -273,9 +277,12 @@ async function processPlotChained( log_index: logIndex, }; - await supabase + const { error: plotError } = await supabase .from("plots") .upsert(row, { onConflict: "tx_hash,log_index" }); + if (plotError) { + throw new Error(`Database error (plot): ${plotError.message}`); + } } async function processDonation( @@ -298,7 +305,10 @@ async function processDonation( log_index: logIndex, }; - await supabase + const { error: donationError } = await supabase .from("donations") .upsert(row, { onConflict: "tx_hash,log_index" }); + if (donationError) { + throw new Error(`Database error (donation): ${donationError.message}`); + } } From 54406496ff1d69f181ff59b4734f878ee3ea50f2 Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Sat, 14 Mar 2026 07:16:46 +0000 Subject: [PATCH 2/2] [#55] Log per-event errors with tx context in backfill catch block Addresses T2a review: bare catch now captures the error and logs tx hash + log index for operator diagnosis instead of silently incrementing the counter. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/api/cron/backfill/route.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/api/cron/backfill/route.ts b/src/app/api/cron/backfill/route.ts index f6c540ec..b4717ea2 100644 --- a/src/app/api/cron/backfill/route.ts +++ b/src/app/api/cron/backfill/route.ts @@ -153,7 +153,10 @@ export async function GET(req: Request) { ); donationsInserted++; } - } catch { + } catch (err) { + const txHash = log.transactionHash ?? "unknown"; + const logIdx = log.logIndex ?? "?"; + console.error(`Backfill error at tx=${txHash} logIndex=${logIdx}:`, err instanceof Error ? err.message : err); errors++; } }