Skip to content

Guard async toolbox/dialog callbacks against torn-down DOM / missing opts (BL-16574)#8081

Draft
hatton wants to merge 1 commit into
masterfrom
BL-16574-sentry-frontend-async-guards
Draft

Guard async toolbox/dialog callbacks against torn-down DOM / missing opts (BL-16574)#8081
hatton wants to merge 1 commit into
masterfrom
BL-16574-sentry-frontend-async-guards

Conversation

@hatton

@hatton hatton commented Jul 20, 2026

Copy link
Copy Markdown
Member

[Claude Sonnet 5] Fix authored by Claude Opus 4.8; this PR was pushed and taken through preflight by Claude Sonnet 5.

Summary

Two small defensive guards for Sentry crash reports on BloomDesktop's front end:

  • TextBoxProperties.fillInLanguageNames() (Sentry BLOOM-DESKTOP-FFJ): the
    editView/getBookLangs callback is async, so the Text Box Properties dialog can already be
    closed — and its elements removed from the DOM — by the time it resolves. The code used a
    non-null assertion (document.getElementById(...)!) and crashed with "Cannot read
    properties of null" when that happened. Now it bails out if the elements are gone.
  • LeveledReaderTool.beginRestoreSettings(opts) (Sentry BLOOM-DESKTOP-FFH): opts can be
    undefined for a book with no saved leveled-reader state, and the code indexed into it
    unconditionally, throwing "Cannot read properties of undefined (reading
    'leveledReaderState')". Now it optional-chains the lookup so it falls through to the
    default-level path instead.

Test plan

  • pnpm typecheck — clean
  • pnpm lint — 0 errors (pre-existing warnings elsewhere untouched)
  • pnpm test:ci (full vitest suite) — 501 passed, 5 skipped, 0 failed
  • Manual repro of both crash scenarios (see QA test-ideas comment on BL-16574)

Ref: https://bloomlibrary.youtrack.cloud/issue/BL-16574

Devin review


This change is Reviewable

…opts (BL-16574)

- TextBoxProperties.fillInLanguageNames(): the getBookLangs callback is
  async, so the Text Box Properties dialog may already be closed and its
  elements removed from the DOM by the time it resolves. Bail out instead
  of throwing on a null getElementById result (Sentry BLOOM-DESKTOP-FFJ).
- LeveledReaderTool.beginRestoreSettings(): opts can be undefined when a
  book has no saved leveled-reader state. Optional-chain the lookup so it
  falls through to the default-level path instead of throwing an
  unhandled rejection that aborts tool activation (Sentry
  BLOOM-DESKTOP-FFH).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hatton

hatton commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

[Claude Sonnet 5] Consulted Devin on 2026-07-20 01:00 UTC up to commit 3c8329d. Result: 0 Bugs, 0 Investigate flags, 1 Informational flag (not posted — low signal; it assessed both guards as legitimate defensive fixes for genuine async lifecycle conditions, consistent with the repo's fail-fast policy which targets API misuse, not this).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant