Fix crash: enrichment held array indices across awaits
CI / build-and-deploy (pull_request) Successful in 30s
CI / build-and-deploy (pull_request) Successful in 30s
`startEnrichment` snapshotted `bookmarks.indices`, then awaited a network call per bookmark. `bookmarks` is replaced wholesale by loads, searches and the unread filter, so by the time the loop read `bookmarks[i]` the index could be out of range — EXC_BREAKPOINT in Array._checkSubscript, straight from the read. The write path already guarded with `i < bookmarks.count`; the read did not. `enrichAll()` had the same shape and the same exposure. Both now track bookmark ids and re-resolve the position after each await, via a shared `apply(summary:tags:toId:)` that skips a bookmark that is no longer loaded rather than writing to whatever now sits at that index — which is the other half of the bug: a stale-but-in-range index would have silently attached one bookmark's summary to another. Found while investigating leftover Spotlight "translation error ... Code=1 (null)" entries after the indexing fix. Those turned out to be a symptom, not a separate bug: the crash tore the process down mid-donation and the in-flight items failed to translate. With the crash fixed they are gone, and the suite went from crashing (0 tests executed) to green across three consecutive runs. Adds a source round-trip to SpotlightRetrievalTests, so both donation paths — app entities and raw searchable items — are covered. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JgLHztZGaEHvS3KNeGQmRM
This commit is contained in:
co-authored by
Claude Opus 5
parent
1995b38b52
commit
2e1b454c09
@@ -37,4 +37,23 @@ struct SpotlightRetrievalTests {
|
||||
"url did not survive the round trip: \(hit.url)")
|
||||
#expect(hit.host == "github.com", "host was \(hit.host)")
|
||||
}
|
||||
|
||||
@Test func indexedSourceIsRetrievable() async throws {
|
||||
let source = IngestedSource(
|
||||
kind: .text,
|
||||
title: "Wqvbnmtest meeting notes",
|
||||
bodyText: "A distinctive probe document about wqvbnmtest.",
|
||||
tags: ["wqvbnmtest"]
|
||||
)
|
||||
await SourceSpotlightIndexer.index([source])
|
||||
var hits: [RetrievedBookmark] = []
|
||||
for _ in 0..<20 {
|
||||
try? await Task.sleep(for: .milliseconds(700))
|
||||
hits = await SpotlightBookmarkSearch.run(query: "wqvbnmtest", limit: 5)
|
||||
if !hits.isEmpty { break }
|
||||
}
|
||||
await SourceSpotlightIndexer.remove(ids: [source.id])
|
||||
#expect(!hits.isEmpty, "Spotlight returned no hits for an indexed source")
|
||||
#expect(hits.first?.title.contains("Wqvbnmtest") == true)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user