fix(cli): don't log benign UNIQUE-constraint dups as store failures

The SQLite backend raises a catchable UNIQUE-constraint exception when an
event is a duplicate id or an older/duplicate replaceable (kind 0/3/10000-
19999) — which the outbox model produces constantly, since each user's
replaceable is fetched from several of their write relays. verifyAndStore
was logging every one as `[cli] store insert failed`, so a full-network
GrapeRank crawl emitted ~294k spurious error lines. The store is behaving
correctly (its partial unique index + trigger keep the newest version and
reject stale copies); the FS backend simply no-ops on the same duplicates.

Suppress UNIQUE-constraint rejections (normal dedup) while still surfacing
genuine persistence failures (I/O, full disk, corruption).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RWk2ZMrGBSr4WenKgwqmbB
This commit is contained in:
Claude
2026-07-07 00:09:44 +00:00
parent 0d6f7fd186
commit c75e0ff1ab
@@ -559,7 +559,17 @@ class Context(
try {
store.insert(event)
} catch (t: Throwable) {
System.err.println("[cli] store insert failed for ${event.id.take(8)}: ${t.message}")
// A UNIQUE-constraint rejection is normal, not a failure: the
// store already holds this id, or a newer version of a
// replaceable (kind 0/3/10000-19999). The outbox model routinely
// delivers the same event from several of a user's write relays,
// so a crawl produces these by the hundred-thousand. Only surface
// genuine persistence failures (I/O, full disk, corruption). The
// FS backend no-ops on such duplicates; this keeps the SQLite
// backend just as quiet.
if (t.message?.contains("UNIQUE constraint", ignoreCase = true) != true) {
System.err.println("[cli] store insert failed for ${event.id.take(8)}: ${t.message}")
}
}
return true
}