fix(newsletter): stop dismissal re-pop loop and add DB write observability#2324
Open
peppescg wants to merge 2 commits into
Open
fix(newsletter): stop dismissal re-pop loop and add DB write observability#2324peppescg wants to merge 2 commits into
peppescg wants to merge 2 commits into
Conversation
…ility The newsletter modal re-pops because the dismissal is never persisted when the SQLite write fails silently. First step of #2321: - setNewsletterDismissedAt now reports whether the dismissal was actually persisted. The renderer suppresses the modal for the rest of the session only when it wasn't — stopping the in-session re-pop loop on a read-only DB or a failed write, while leaving the normal (persisted) flow unchanged. - Instrument DB write failures in Sentry, separating Bucket A (read-only DB: on-disk schema newer than the app, captured in the migrator with applied vs known schema) from Bucket B (the write threw, captured with the SQLite error code). os.name / release are attached automatically. Today these failures are invisible — Bucket A doesn't even produce a local log. Refs #2321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
9391d43 to
06ca195
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR addresses the newsletter modal “dismiss → re-show” loop when the dismissal cannot be persisted to SQLite, and adds main-process Sentry telemetry to observe (a) “DB forced read-only due to schema newer than app” and (b) “SQLite write threw” failures.
Changes:
- Changed the dismissal IPC contract so
setNewsletterDismissedAtreturnsbooleanindicating whether the dismissal was persisted. - Updated the renderer modal to suppress re-showing within the same session when persistence fails, plus added a regression test for this behavior.
- Added DB write failure telemetry (Bucket A via migrator; Bucket B via settings writer) with schema / SQLite code context.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| renderer/src/common/mocks/electronAPI.ts | Updates mock return type for setNewsletterDismissedAt to boolean. |
| renderer/src/common/components/newsletter-modal.tsx | Uses persisted/not-persisted result to avoid in-session re-pop loop. |
| renderer/src/common/components/tests/newsletter-modal.test.tsx | Adds regression coverage for “cannot persist dismissal” session behavior. |
| preload/src/api/app.ts | Updates preload API typing for setNewsletterDismissedAt to return Promise<boolean>. |
| main/src/tests/newsletter.test.ts | Updates unit tests for new boolean contract and read-only / throw scenarios. |
| main/src/newsletter.ts | Makes setNewsletterDismissedAt return persisted status; skips on read-only. |
| main/src/db/writers/settings-writer.ts | Captures and reports thrown write failures (Bucket B) before rethrowing. |
| main/src/db/telemetry.ts | Adds captureDbReadOnly and captureDbWriteFailure Sentry helpers. |
| main/src/db/migrator.ts | Captures schema-newer read-only condition (Bucket A) when disabling writes. |
Address PR review: the schema versions were interpolated into the captureMessage string, which Sentry uses for grouping and would fragment the signal into a separate issue per schema combo. Use a fixed message and keep the versions in extras. Refs #2321 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
First step of #2321. The newsletter modal re-pops and won't stay dismissed because the dismissal is never persisted when the SQLite write fails silently — users then submit junk emails to make it go away (the "newsletter spam"). This PR stops the worst symptom and, crucially, adds the telemetry we're missing so we can measure how often this actually happens before investing in deeper fixes.
It deliberately does not change the read-only DB behavior or add filesystem mitigations — those are follow-ups (PR2/PR3 in #2321), gated on the data this PR collects.
Changes
1. Stop the in-session re-pop loop (only when persistence fails)
setNewsletterDismissedAtnow returns whether the dismissal was actually persisted (false= read-only DB or a failed write).2. Observe DB write failures in Sentry, split by bucket
appliedvsknownschema. This path is currently completely silent (not even a local log).SQLITE_*code.os.name/releaseare attached automatically by@sentry/electron, so we can see which OS/versions are affected.Testing
pnpm type-check✅,eslinton changed files ✅main/src/tests/newsletter.test.ts✅ (added coverage for the new boolean contract: persisted/read-only/throws)main/src/db/__tests__(migrator + writers) ✅Refs #2321