fix(pdf-import): tag chapters by the studyset tree root #832

Merged
raisondetredev merged 1 commit from refs/pull/832/head into main 2026-08-10 11:49:13 +02:00
raisondetredev commented 2026-08-10 11:48:56 +02:00 (Migrated from codeberg.org)

Creating a card in a sub-studyset failed its chapter auto-tag with a
UNIQUE violation on (root_studyset_id, kind, name).

Tags are pooled per inheritance tree: listForTree and the unique index
are both keyed by root_studyset_id. The import screen passed the
studyset the PDF lives in instead, so for a PDF in a sub-studyset the
lookup matched nothing (no tag has a sub-studyset as its root),
find-or-create degraded into create-always, and the insert collided
with the chapter tag already in the tree. Resolve the root with
rootStudysetIdOf, memoised per session, in the bloc and in the
screen's chapter-suggestion lookup.

The collision then surfaced raw instead of taking the bloc's
raced-with-a-concurrent-create retry: TagRepository classified
duplicates with on SqliteException, but the local database runs
behind drift's remote layer (background isolate on native, web worker
on web), so the exception arrives wrapped in a DriftRemoteException
that clause can't catch and fell through to UnknownTagException.
Classify on the rendered text instead - DriftRemoteException.toString
delegates to its cause, and the constraint text lives in explanation,
which only toString includes.

Creating a card in a sub-studyset failed its chapter auto-tag with a UNIQUE violation on (root_studyset_id, kind, name). Tags are pooled per inheritance tree: listForTree and the unique index are both keyed by root_studyset_id. The import screen passed the studyset the PDF lives in instead, so for a PDF in a sub-studyset the lookup matched nothing (no tag has a sub-studyset as its root), find-or-create degraded into create-always, and the insert collided with the chapter tag already in the tree. Resolve the root with rootStudysetIdOf, memoised per session, in the bloc and in the screen's chapter-suggestion lookup. The collision then surfaced raw instead of taking the bloc's raced-with-a-concurrent-create retry: TagRepository classified duplicates with `on SqliteException`, but the local database runs behind drift's remote layer (background isolate on native, web worker on web), so the exception arrives wrapped in a DriftRemoteException that clause can't catch and fell through to UnknownTagException. Classify on the rendered text instead - DriftRemoteException.toString delegates to its cause, and the constraint text lives in `explanation`, which only toString includes.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
project-halkyon/halkyon-learn!832
No description provided.