Skip to content

Prevent local errors from reaching production Sentry - #1882

Merged
Asherlc merged 2 commits into
mainfrom
Asherlc/investigate-sentry-errors
Jul 24, 2026
Merged

Asherlc merged 2 commits into
mainfrom
Asherlc/investigate-sentry-errors

Conversation

@Asherlc

@Asherlc Asherlc commented Jul 24, 2026 •

Copy link
Copy Markdown
Owner

Summary

Centralize Sentry initialization and require an explicit prod or production deployment environment, preventing local processes that inherit the production DSN from reporting errors.
Pass the existing deployment environment into production web and worker containers, explicitly tag their events as production, and document the operational contract and incident findings.
Add regression coverage for local suppression, production initialization, server delegation, and worker startup.

Testing

pnpm lint; root, server, and web TypeScript checks; pnpm test (13,131 passed, 21 skipped).


Summary by cubic

Prevents local processes from sending errors to production Sentry by centralizing Sentry init, gating it on DEPLOY_ENVIRONMENT, and ensuring it only initializes once. Production web and worker now tag events with the production environment.

  • Bug Fixes

    • Added initProductionSentry (src/lib/sentry.ts) that initializes only when a DSN is present and DEPLOY_ENVIRONMENT is prod or production, sets environment: "production", and is idempotent.
    • Updated server and worker to delegate to dofek/lib/sentry; replaced direct @sentry/node init in the worker; added tests for local suppression, production init, idempotency, and worker startup; exported ./lib/sentry in package.json.
    • Passed DEPLOY_ENVIRONMENT to web and worker in deploy/stack.yml (default production); clarified behavior in deploy/README.md and documented the incident in docs/production-incident-baseline.md.
  • Migration

    • If you deploy outside deploy/stack.yml, set DEPLOY_ENVIRONMENT=production for any production web/worker. Leave it unset or non-prod for local and staging.

Written for commit 64a8f24. Summary will update on new commits.

Review in cubic

Copilot AI review requested due to automatic review settings July 24, 2026 00:48
@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@cursor

cursor Bot commented Jul 24, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @Asherlc, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

@Asherlc, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 43 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e4cec73d-4801-4d34-a4e4-1680ce52761d

📥 Commits

Reviewing files that changed from the base of the PR and between d47e49b and 64a8f24.

📒 Files selected for processing (10)
  • deploy/README.md
  • deploy/stack.yml
  • docs/production-incident-baseline.md
  • package.json
  • packages/server/src/lib/sentry.test.ts
  • packages/server/src/lib/sentry.ts
  • src/jobs/worker.test.ts
  • src/jobs/worker.ts
  • src/lib/sentry.test.ts
  • src/lib/sentry.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Storybook previews for f38d4ad6 are ready:

This comment updates automatically on each PR push.

@greptile-apps

greptile-apps Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

Greptile Summary

This PR centralizes Sentry initialization behind an initProductionSentry helper that gates on both DSN presence and an explicit DEPLOY_ENVIRONMENT of prod or production, preventing local processes that inherit the production DSN from reporting errors. Both prior review findings — the absent idempotency guard in the shared helper and the missing test for DEPLOY_ENVIRONMENT being entirely unset — have been resolved in this revision.

  • src/lib/sentry.ts: New shared initProductionSentry with its own let initialized = false guard, environment allowlist check, and environment: "production" tag; exported via package.json as dofek/lib/sentry.
  • packages/server/src/lib/sentry.ts and src/jobs/worker.ts: Both delegate to initProductionSentry, removing their direct Sentry.init calls; deploy/stack.yml now passes DEPLOY_ENVIRONMENT=production (with a safe default) to both production containers.
  • Tests: Five new focused tests in src/lib/sentry.test.ts cover no-DSN, absent env, non-prod env, both allowlisted values, and the idempotency contract; worker and server tests updated to match the new delegation path.

Confidence Score: 5/5

Safe to merge — the change is purely additive and reduces surface area: local processes can no longer reach production Sentry even when they inherit the DSN.

Both issues flagged in earlier review rounds (absent idempotency guard in the shared helper and missing test for an unset DEPLOY_ENVIRONMENT) are addressed in this revision. The shared initializer correctly sequences its guards, the server and worker delegation paths preserve skipOpenTelemetrySetup, the stack.yml default is intentional and documented, and the five new unit tests provide direct regression coverage for the core guard being added.

No files require special attention.

Important Files Changed

Filename Overview
src/lib/sentry.ts New shared helper with idempotency guard, environment allowlist, and production environment tag; logic is correct and clean.
src/lib/sentry.test.ts Five tests cover: no DSN, absent DEPLOY_ENVIRONMENT, non-prod env, both allowlisted values ("prod" / "production"), and double-call idempotency. Addresses both previously flagged test gaps.
packages/server/src/lib/sentry.ts Server wrapper correctly retains its own initialized guard, delegates to initProductionSentry, and preserves the skipOpenTelemetrySetup behavior via the shared helper.
src/jobs/worker.ts Module-level Sentry init replaced with initProductionSentry call; skipOpenTelemetrySetup is now applied through the shared helper, preserving prior behavior.
deploy/stack.yml DEPLOY_ENVIRONMENT added to both web and worker services with a safe default of "production"; the shell-variable passthrough allows overriding at deploy time.
packages/server/src/lib/sentry.test.ts Tests updated to mock dofek/lib/sentry and verify delegation rather than direct Sentry.init calls; idempotency via server's own guard is validated.
src/jobs/worker.test.ts Hoisted setup adds DEPLOY_ENVIRONMENT="prod" before module load, and the init assertion now includes environment: "production" to match the new shared helper contract.
package.json Adds ./lib/sentry export so the server package can import the shared helper via dofek/lib/sentry.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Server: initSentry] --> B{server initialized?}
    B -- yes --> Z[return no-op]
    B -- no --> C[set server initialized = true]
    C --> D[initProductionSentry dsn]
    W[Worker module load] --> D
    D --> E{shared initialized?}
    E -- yes --> Z
    E -- no --> F{DSN present?}
    F -- no --> Z
    F -- yes --> G{DEPLOY_ENVIRONMENT == prod or production?}
    G -- no --> Z
    G -- yes --> H[Sentry.init with environment production and skipOpenTelemetrySetup true]
    H --> I[set shared initialized = true]
    style H fill:#2d9,color:#fff
    style Z fill:#ccc
Loading

Reviews (2): Last reviewed commit: "fix: make Sentry initialization idempote..." | Re-trigger Greptile

Comment thread src/lib/sentry.ts
Comment thread src/lib/sentry.test.ts Outdated
@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@Asherlc
Asherlc merged commit 7eba92d into main Jul 24, 2026
105 checks passed
@Asherlc
Asherlc deleted the Asherlc/investigate-sentry-errors branch July 24, 2026 01:53
posthog Bot added a commit that referenced this pull request Jul 30, 2026
…tion

worker.test.ts assigned DEPLOY_ENVIRONMENT="prod" and SENTRY_DSN directly on
process.env inside vi.hoisted() and never restored them. The "prod"
classification persisted for the entire vitest fork, defeating the
production-only guard in initProductionSentry() for every module in that fork —
the same failure mode 7eba92d (#1882) fixed for Sentry. Any un-mocked telemetry
sink wired to that guard would then ship local test-fixture errors to
production error tracking.

- Use tracked vi.stubEnv and restore with vi.unstubAllEnvs() in afterAll so the
  classification cannot outlive the test file within a reused fork.
- Add an explicit non-production DEPLOY_ENVIRONMENT="test" default to the shared
  test env so no test run is ever classified as a production deployment unless
  it opts in.
- Record the recurrence in docs/production-incident-baseline.md.

Generated-By: PostHog Code
Task-Id: 0fd126a1-18dd-4b16-a4cc-a990b91ce4aa
Asherlc added a commit that referenced this pull request Jul 31, 2026
…tion (#2348)

* fix(test): stop worker test from classifying the whole fork as production

worker.test.ts assigned DEPLOY_ENVIRONMENT="prod" and SENTRY_DSN directly on
process.env inside vi.hoisted() and never restored them. The "prod"
classification persisted for the entire vitest fork, defeating the
production-only guard in initProductionSentry() for every module in that fork —
the same failure mode 7eba92d (#1882) fixed for Sentry. Any un-mocked telemetry
sink wired to that guard would then ship local test-fixture errors to
production error tracking.

- Use tracked vi.stubEnv and restore with vi.unstubAllEnvs() in afterAll so the
  classification cannot outlive the test file within a reused fork.
- Add an explicit non-production DEPLOY_ENVIRONMENT="test" default to the shared
  test env so no test run is ever classified as a production deployment unless
  it opts in.
- Record the recurrence in docs/production-incident-baseline.md.

Generated-By: PostHog Code
Task-Id: 0fd126a1-18dd-4b16-a4cc-a990b91ce4aa

* fix(ci): merge main and repair report/sync regressions blocking checks

Bring the branch up to date with main and fix downstream breakages from the
report empty-state work and provider sync refactor that were failing lint,
typecheck, unit, and mobile tests in CI.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(dev): use MISE_LOCKED=1 instead of mise trust for installs

Replace mise trust with explicit MISE_LOCKED=1 on install commands so
pinned tool versions are enforced without relying on mise.toml settings.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(ci): repair unit, integration, e2e, and iOS build failures

Align withings timeout expectations with ProviderRequestTimeoutError, pass endDate in monthly report integration tests, lowercase GHCR cache refs for fork repos, and defer HealthKit observer coordinator init to avoid self capture in Swift.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web): align report fixtures with MonthlyReportData types

Remove recovery fields from component stories and tests since web UI
consumes repository data shapes, not router results. Delete the unused
report-data fixture that was breaking Knip, coverage, and Stryker.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: cite Vitest sources in worker env leak incident entry

Add primary-source links for vi.hoisted, fork worker env sharing, vi.stubEnv,
vi.unstubAllEnvs, and module mocking per review feedback. Also use "unmocked".

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(test): restore only worker env stubs in afterAll

Use targeted vi.stubEnv calls instead of vi.unstubAllEnvs so future tests
in worker.test.ts can stub other env vars without implicit teardown.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: cite Sentry and PostHog SDKs in env leak incident entry

Add official SDK documentation links for @sentry/node and posthog-node
claims to satisfy third-party citation compliance in the incident baseline.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: posthog[bot] <206114724+posthog[bot]@users.noreply.github.com>
Co-authored-by: Asher Cohen <asherlc@asherlc.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
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.

2 participants