Skip to content

fix: unified error notification system for user-fixable errors#1183

Merged
elie222 merged 5 commits intomainfrom
fix/unified-error-notifications
Jan 4, 2026
Merged

fix: unified error notification system for user-fixable errors#1183
elie222 merged 5 commits intomainfrom
fix/unified-error-notifications

Conversation

@elie222
Copy link
Owner

@elie222 elie222 commented Jan 4, 2026

User description

Send one-time email notifications when users have API key issues, insufficient credits, or Microsoft auth expiration.

  • Add ActionRequiredEmail template for API/auth errors with configurable error type, message, and action button
  • Add addUserErrorMessageWithNotification() helper that sends email only once per error type (tracks emailSentAt in existing errorMessages JSON field)
  • Integrate cleanupInvalidTokens() into Outlook client to handle Microsoft auth expiration (clears tokens, sends reconnection email, prevents repeated errors)
  • Update LLM error handler to use unified notification for: incorrect API key, invalid model, deactivated key, quota exceeded, insufficient Anthropic balance
  • Clear error messages when user updates AI settings (allows re-notification if new settings are also invalid)

Generated description

Below is a concise technical summary of the changes proposed in this PR:

graph LR
    subgraph "@inboxzero/resend" ["@inboxzero/resend"]
    sendActionRequiredEmail_("sendActionRequiredEmail"):::added
    ActionRequiredEmail_("ActionRequiredEmail"):::added
    Footer_("Footer"):::added
    REACT_EMAIL_COMPONENTS_("REACT_EMAIL_COMPONENTS"):::added
    sendActionRequiredEmail_ -- "Sends ActionRequiredEmail with error details and unsubscribeToken" --> ActionRequiredEmail_
    ActionRequiredEmail_ -- "Embeds Footer providing unsubscribe, support, and privacy links" --> Footer_
    ActionRequiredEmail_ -- "Uses react-email components to build actionable error email" --> REACT_EMAIL_COMPONENTS_
    Footer_ -- "Uses react-email components to render footer links" --> REACT_EMAIL_COMPONENTS_
    classDef added stroke:#15AA7A
    classDef removed stroke:#CD5270
    classDef modified stroke:#EDAC4C
    linkStyle default stroke:#CBD5E1,font-size:13px
    end
    subgraph "inbox-zero-ai" ["inbox-zero-ai"]
    handleError_("handleError"):::modified
    addUserErrorMessageWithNotification_("addUserErrorMessageWithNotification"):::added
    PRISMA_("PRISMA"):::modified
    RESEND_("RESEND"):::added
    clearUserErrorMessages_("clearUserErrorMessages"):::modified
    handleLinkAccount_("handleLinkAccount"):::modified
    saveTokens_("saveTokens"):::modified
    handleError_ -- "Replaces silent adds with notifications and emails for AI errors." --> addUserErrorMessageWithNotification_
    addUserErrorMessageWithNotification_ -- "Persists error entry with emailSentAt, updating user's errorMessages." --> PRISMA_
    addUserErrorMessageWithNotification_ -- "Sends action-required email with unsubscribe token and action link." --> RESEND_
    clearUserErrorMessages_ -- "Clears user's errorMessages via Prisma, logging failures." --> PRISMA_
    handleLinkAccount_ -- "Clears error messages upon account link, using logger." --> clearUserErrorMessages_
    saveTokens_ -- "Clears AI error messages after saving tokens, using logger." --> clearUserErrorMessages_
    classDef added stroke:#15AA7A
    classDef removed stroke:#CD5270
    classDef modified stroke:#EDAC4C
    linkStyle default stroke:#CBD5E1,font-size:13px
    end
Loading

Implement a unified error notification system to send one-time email alerts for user-fixable issues like API key problems, insufficient credits, or Microsoft authentication expiration. Enhance error message management by clearing relevant errors when users update AI settings and integrating the new notification flow into LLM error handling and Outlook client token cleanup.

TopicDetails
Unified Error Notifications Implement a unified system to send one-time email notifications for user-fixable errors, utilizing a new ActionRequiredEmail template and the addUserErrorMessageWithNotification helper.
Modified files (6)
  • packages/resend/emails/action-required.tsx
  • packages/resend/src/send.tsx
  • apps/web/utils/llms/index.ts
  • apps/web/utils/auth/cleanup-invalid-tokens.ts
  • apps/web/utils/error-messages/index.ts
  • apps/web/utils/outlook/client.ts
Latest Contributors(1)
UserCommitDate
elie222fixesJanuary 01, 2026
Error Message Lifecycle Manage the lifecycle of user error messages by introducing clearSpecificErrorMessages to remove errors when AI settings are updated, integrating cleanupInvalidTokens for Microsoft auth expiration, and ensuring consistent logger propagation.
Modified files (7)
  • apps/web/utils/error-messages/index.ts
  • apps/web/utils/auth.ts
  • apps/web/utils/actions/settings.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/actions/error-messages.ts
Latest Contributors(2)
UserCommitDate
elie222fixesJanuary 01, 2026
eduardoleliss@gmail.comDigest-email-fixesJuly 07, 2025
This pull request is reviewed by Baz. Review like a pro on (Baz).

@vercel
Copy link

vercel bot commented Jan 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
inbox-zero Ready Ready Preview Jan 4, 2026 7:47am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 4, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Logger context is threaded through error utilities and callers; error-message APIs were extended to support selective clearing and one-off "action required" email notifications (with unsubscribe tokens). Call sites updated to pass logger and to use the new notification API where applicable.

Changes

Cohort / File(s) Summary
Error Message Utility Core
apps/web/utils/error-messages/index.ts
Threaded Logger into APIs; ErrorMessageEntry gains emailSentAt?; added addUserErrorMessageWithNotification, clearSpecificErrorMessages, email sending (unsubscribe token), and errorType→UI/action config. Signatures updated for addUserErrorMessage, clearUserErrorMessages, and new clearSpecificErrorMessages.
Action & Auth Call Sites
apps/web/utils/actions/error-messages.ts, apps/web/utils/actions/settings.ts, apps/web/utils/auth.ts, apps/web/utils/auth/cleanup-invalid-tokens.ts
Call sites destructure and pass ctx.logger to error-message APIs; updateAiSettingsAction calls clearSpecificErrorMessages. Test assertions loosened to accept objectContaining for logger-propagated calls.
LLM Error Handling
apps/web/utils/llms/index.ts
Replaced addUserErrorMessage(...) calls with addUserErrorMessageWithNotification({ userId, userEmail, emailAccountId, errorType, errorMessage, logger }) across multiple error branches.
Outlook Token Refresh
apps/web/utils/outlook/client.ts
On invalid_grant during refresh, invokes cleanupInvalidTokens(emailAccountId, logger) before throwing SafeError.
Email Templates & Sender
packages/resend/emails/action-required.tsx, packages/resend/src/send.tsx
Added ActionRequiredEmail component and sendActionRequiredEmail helper (accepts ActionRequiredEmailProps, includes category action-required).
Tests & Test Helpers
apps/web/utils/auth.test.ts, apps/web/utils/auth/cleanup-invalid-tokens.test.ts, apps/web/utils/meeting-briefs/recipient-context.test.ts
Tests updated to use module-scoped scoped logger and to expect logger-containing calls; assertions adjusted for additional logger fields.

Sequence Diagram

sequenceDiagram
    autonumber
    participant LLM as LLM/Error Handler
    participant ErrMod as Error Messages Module
    participant DB as Database
    participant Mail as Resend Sender
    participant SMTP as Resend Service

    Note over LLM,ErrMod: per-request logger + user email/account info included
    LLM->>ErrMod: addUserErrorMessageWithNotification({ userId, userEmail, emailAccountId, errorType, errorMessage, logger })
    ErrMod->>DB: lookup existing error entry for (userId, errorType)
    DB-->>ErrMod: entry (maybe with emailSentAt)
    alt email not sent yet
        ErrMod->>Mail: render + sendActionRequiredEmail({..., unsubscribeToken })
        Mail->>SMTP: deliver email (category: action-required)
        SMTP-->>Mail: delivery result
        Mail-->>ErrMod: success/failure
        ErrMod->>DB: persist/update entry with `emailSentAt` and token (on success)
    else already sent
        ErrMod->>DB: update/ensure entry exists (no new email)
    end
    ErrMod-->>LLM: completed
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I nibbled logs and found a thread,

Emails hop when errors spread,
One-time links and tokens neat,
Cleared the stale, kept carrots sweet,
Inbox-zero, hop to greet! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'fix: unified error notification system for user-fixable errors' directly and clearly summarizes the main change: implementing a unified error notification system.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d29d4b0 and 2439bbe.

📒 Files selected for processing (4)
  • apps/web/utils/auth.test.ts
  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/llms/index.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/utils/llms/index.ts
🧰 Additional context used
📓 Path-based instructions (17)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/data-fetching.mdc)

**/*.{ts,tsx}: For API GET requests to server, use the swr package
Use result?.serverError with toastError from @/components/Toast for error handling in async operations

**/*.{ts,tsx}: Use wrapper functions for Gmail message operations (get, list, batch, etc.) from @/utils/gmail/message.ts instead of direct API calls
Use wrapper functions for Gmail thread operations from @/utils/gmail/thread.ts instead of direct API calls
Use wrapper functions for Gmail label operations from @/utils/gmail/label.ts instead of direct API calls

**/*.{ts,tsx}: For early access feature flags, create hooks using the naming convention use[FeatureName]Enabled that return a boolean from useFeatureFlagEnabled("flag-key")
For A/B test variant flags, create hooks using the naming convention use[FeatureName]Variant that define variant types, use useFeatureFlagVariantKey() with type casting, and provide a default "control" fallback
Use kebab-case for PostHog feature flag keys (e.g., inbox-cleaner, pricing-options-2)
Always define types for A/B test variant flags (e.g., type PricingVariant = "control" | "variant-a" | "variant-b") and provide type safety through type casting

**/*.{ts,tsx}: Don't use primitive type aliases or misleading types
Don't use empty type parameters in type aliases and interfaces
Don't use this and super in static contexts
Don't use any or unknown as type constraints
Don't use the TypeScript directive @ts-ignore
Don't use TypeScript enums
Don't export imported variables
Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions
Don't use TypeScript namespaces
Don't use non-null assertions with the ! postfix operator
Don't use parameter properties in class constructors
Don't use user-defined types
Use as const instead of literal types and type annotations
Use either T[] or Array<T> consistently
Initialize each enum member value explicitly
Use export type for types
Use `impo...

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/prisma-enum-imports.mdc)

Always import Prisma enums from @/generated/prisma/enums instead of @/generated/prisma/client to avoid Next.js bundling errors in client components

Import Prisma using the project's centralized utility: import prisma from '@/utils/prisma'

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

Import specific lodash functions rather than entire lodash library to minimize bundle size (e.g., import groupBy from 'lodash/groupBy')

apps/web/**/*.{ts,tsx}: Use TypeScript with strict null checks
Do not export types/interfaces that are only used within the same file. Export later if needed

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/security.mdc)

**/*.ts: ALL database queries MUST be scoped to the authenticated user/account by including user/account filtering in WHERE clauses to prevent unauthorized data access
Always validate that resources belong to the authenticated user before performing operations, using ownership checks in WHERE clauses or relationships
Always validate all input parameters for type, format, and length before using them in database queries
Use SafeError for error responses to prevent information disclosure. Generic error messages should not reveal internal IDs, logic, or resource ownership details
Only return necessary fields in API responses using Prisma's select option. Never expose sensitive data such as password hashes, private keys, or system flags
Prevent Insecure Direct Object References (IDOR) by validating resource ownership before operations. All findUnique/findFirst calls MUST include ownership filters
Prevent mass assignment vulnerabilities by explicitly whitelisting allowed fields in update operations instead of accepting all user-provided data
Prevent privilege escalation by never allowing users to modify system fields, ownership fields, or admin-only attributes through user input
All findMany queries MUST be scoped to the user's data by including appropriate WHERE filters to prevent returning data from other users
Use Prisma relationships for access control by leveraging nested where clauses (e.g., emailAccount: { id: emailAccountId }) to validate ownership

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

**/*.{tsx,ts}: Use Shadcn UI and Tailwind for components and styling
Use next/image package for images
For API GET requests to server, use the swr package with hooks like useSWR to fetch data
For text inputs, use the Input component with registerProps for form integration and error handling

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
**/*.{tsx,ts,css}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

Implement responsive design with Tailwind CSS using a mobile-first approach

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{js,jsx,ts,tsx}: Don't use accessKey attribute on any HTML element
Don't set aria-hidden="true" on focusable elements
Don't add ARIA roles, states, and properties to elements that don't support them
Don't use distracting elements like <marquee> or <blink>
Only use the scope prop on <th> elements
Don't assign non-interactive ARIA roles to interactive HTML elements
Make sure label elements have text content and are associated with an input
Don't assign interactive ARIA roles to non-interactive HTML elements
Don't assign tabIndex to non-interactive HTML elements
Don't use positive integers for tabIndex property
Don't include "image", "picture", or "photo" in img alt prop
Don't use explicit role property that's the same as the implicit/default role
Make static elements with click handlers use a valid role attribute
Always include a title element for SVG elements
Give all elements requiring alt text meaningful information for screen readers
Make sure anchors have content that's accessible to screen readers
Assign tabIndex to non-interactive HTML elements with aria-activedescendant
Include all required ARIA attributes for elements with ARIA roles
Make sure ARIA properties are valid for the element's supported roles
Always include a type attribute for button elements
Make elements with interactive roles and handlers focusable
Give heading elements content that's accessible to screen readers (not hidden with aria-hidden)
Always include a lang attribute on the html element
Always include a title attribute for iframe elements
Accompany onClick with at least one of: onKeyUp, onKeyDown, or onKeyPress
Accompany onMouseOver/onMouseOut with onFocus/onBlur
Include caption tracks for audio and video elements
Use semantic elements instead of role attributes in JSX
Make sure all anchors are valid and navigable
Ensure all ARIA properties (aria-*) are valid
Use valid, non-abstract ARIA roles for elements with ARIA roles
Use valid AR...

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
**/*.{test,spec}.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{test,spec}.{js,jsx,ts,tsx}: Don't nest describe() blocks too deeply in test files
Don't use callbacks in asynchronous tests and hooks
Don't have duplicate hooks in describe blocks
Don't use export or module.exports in test files
Don't use focused tests
Make sure the assertion function, like expect, is placed inside an it() function call
Don't use disabled tests

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
!(pages/_document).{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

Don't use the next/head module in pages/_document.js on Next.js projects

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)

**/*.{js,ts,jsx,tsx}: Use lodash utilities for common operations (arrays, objects, strings)
Import specific lodash functions to minimize bundle size (e.g., import groupBy from 'lodash/groupBy')

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
**/{utils,helpers,lib}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/logging.mdc)

Logger should be passed as a parameter to helper functions instead of creating their own logger instances

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
apps/web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

apps/web/**/*.{ts,tsx,js,jsx}: Use @/ path aliases for imports from project root
Prefer self-documenting code over comments; use descriptive variable and function names instead of explaining intent with comments
Add helper functions to the bottom of files, not the top
All imports go at the top of files, no mid-file dynamic imports

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
apps/web/**/*.{ts,tsx,js,jsx,json,css}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

Format code with Prettier

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
apps/web/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

Co-locate test files next to source files (e.g., utils/example.test.ts). Only E2E and AI tests go in __tests__/

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
apps/web/**/*.{example,ts,json}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

Add environment variables to .env.example, env.ts, and turbo.json

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

**/*.test.{ts,tsx}: Use vitest as the testing framework
Colocate test files next to the tested file with .test.ts or .test.tsx naming convention (e.g., dir/format.ts and dir/format.test.ts)
Mock server-only using vi.mock("server-only", () => ({}))
Mock Prisma using vi.mock("@/utils/prisma") and the provided mock from @/utils/__mocks__/prisma
Use test helper functions getEmail, getEmailAccount, and getRule from @/__tests__/helpers for creating mock data
Clear all mocks between tests using beforeEach(() => { vi.clearAllMocks(); })
Use descriptive test names that clearly indicate what is being tested
Do not mock the Logger in tests

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
**/*.test.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/notes.mdc)

Co-locate test files next to source files (e.g., utils/example.test.ts). Only E2E and AI tests go in __tests__/

Files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
🧠 Learnings (25)
📓 Common learnings
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : Use descriptive scoped loggers for each LLM feature, log inputs and outputs with appropriate log levels, and include relevant context in log messages
📚 Learning: 2025-11-25T14:37:56.430Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.430Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Prefer using existing helpers from `@/__tests__/helpers.ts` (`getEmailAccount`, `getEmail`, `getRule`, `getMockMessage`, `getMockExecutedRule`) instead of creating custom test data helpers

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : Use descriptive scoped loggers for each LLM feature, log inputs and outputs with appropriate log levels, and include relevant context in log messages

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2025-12-18T16:37:47.972Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/logging.mdc:0-0
Timestamp: 2025-12-18T16:37:47.972Z
Learning: Applies to **/{scripts,tests,__tests__}/**/*.{ts,tsx} : Use createScopedLogger only for code that doesn't run within a middleware chain, such as standalone scripts or tests

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2026-01-01T10:42:29.775Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2026-01-01T10:42:29.775Z
Learning: Applies to **/*.test.{ts,tsx} : Do not mock the Logger in tests

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2026-01-01T10:42:29.775Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2026-01-01T10:42:29.775Z
Learning: Applies to **/*.test.{ts,tsx} : Use test helper functions `getEmail`, `getEmailAccount`, and `getRule` from `@/__tests__/helpers` for creating mock data

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
  • apps/web/utils/auth.test.ts
📚 Learning: 2025-12-18T16:37:47.972Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/logging.mdc:0-0
Timestamp: 2025-12-18T16:37:47.972Z
Learning: Applies to **/{utils,helpers,lib}/**/*.{ts,tsx} : Logger should be passed as a parameter to helper functions instead of creating their own logger instances

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : LLM feature functions must import from `zod` for schema validation, use `createScopedLogger` from `@/utils/logger`, `chatCompletionObject` and `createGenerateObject` from `@/utils/llms`, and import `EmailAccountWithAI` type from `@/utils/llms/types`

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2025-11-25T14:37:56.430Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.430Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Use `console.debug()` for outputting generated LLM content in tests, e.g., `console.debug("Generated content:\n", result.content);`

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
📚 Learning: 2025-11-25T14:37:56.430Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.430Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Use `describe.runIf(isAiTest)` with environment variable `RUN_AI_TESTS === "true"` to conditionally run LLM tests

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
📚 Learning: 2025-11-25T14:39:23.326Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:23.326Z
Learning: Applies to **/*.test.ts : Include security tests in test suites to verify: authentication is required, IDOR protection works (other users cannot access resources), parameter validation rejects invalid inputs, and error messages don't leak information

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/auth.test.ts
📚 Learning: 2026-01-01T10:42:29.775Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2026-01-01T10:42:29.775Z
Learning: Applies to **/*.test.{ts,tsx} : Mock Prisma using `vi.mock("@/utils/prisma")` and the provided mock from `@/utils/__mocks__/prisma`

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2025-11-25T14:37:56.430Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.430Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Mock 'server-only' module with empty object in LLM test files: `vi.mock("server-only", () => ({}))`

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2026-01-01T10:42:29.775Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2026-01-01T10:42:29.775Z
Learning: Applies to **/*.test.{ts,tsx} : Mock `server-only` using `vi.mock("server-only", () => ({}))`

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2026-01-01T10:42:29.775Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2026-01-01T10:42:29.775Z
Learning: Applies to **/*.test.{ts,tsx} : Clear all mocks between tests using `beforeEach(() => { vi.clearAllMocks(); })`

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2025-12-18T16:37:47.972Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/logging.mdc:0-0
Timestamp: 2025-12-18T16:37:47.972Z
Learning: Applies to **/{app,pages}/**/{route,+page}.{ts,tsx} : Use middleware wrappers (withError, withAuth, withEmailAccount, withEmailProvider) that automatically create loggers with request context in API routes

Applied to files:

  • apps/web/utils/auth/cleanup-invalid-tokens.test.ts
📚 Learning: 2025-12-18T16:37:47.972Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/logging.mdc:0-0
Timestamp: 2025-12-18T16:37:47.972Z
Learning: Applies to **/*.{ts,tsx} : Avoid using .with() for global/file-level loggers; only use .with() within specific functions for context enrichment

Applied to files:

  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2025-12-18T16:37:47.972Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/logging.mdc:0-0
Timestamp: 2025-12-18T16:37:47.972Z
Learning: Applies to **/*.action.{ts,tsx} : Use actionClient context to receive logger automatically in server actions, accessing it via ctx.logger

Applied to files:

  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2025-12-18T16:37:47.972Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/logging.mdc:0-0
Timestamp: 2025-12-18T16:37:47.972Z
Learning: Applies to **/{app,pages}/**/{route,+page}.{ts,tsx} : Enrich logger context within route handlers using logger.with() to add request-specific fields like messageId

Applied to files:

  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2025-11-25T14:37:56.430Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.430Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Use vitest imports (`describe`, `expect`, `test`, `vi`, `beforeEach`) in LLM test files

Applied to files:

  • apps/web/utils/meeting-briefs/recipient-context.test.ts
📚 Learning: 2025-11-25T14:39:27.909Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:27.909Z
Learning: Applies to **/app/api/**/*.ts : Use `withAuth` middleware for user-level operations such as user settings, API keys, and referrals that use only `userId`

Applied to files:

  • apps/web/utils/auth.test.ts
📚 Learning: 2026-01-01T10:42:29.775Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2026-01-01T10:42:29.775Z
Learning: Applies to **/*.test.{ts,tsx} : Use descriptive test names that clearly indicate what is being tested

Applied to files:

  • apps/web/utils/auth.test.ts
📚 Learning: 2025-11-25T14:39:23.326Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:23.326Z
Learning: Applies to app/api/**/*.ts : Use `SafeError` for error responses to prevent information disclosure - provide generic messages (e.g., 'Rule not found' not 'Rule {id} does not exist for user {userId}') without revealing internal IDs or ownership details

Applied to files:

  • apps/web/utils/auth.test.ts
📚 Learning: 2025-11-25T14:39:27.909Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:27.909Z
Learning: Applies to **/*.ts : Prevent mass assignment vulnerabilities by explicitly whitelisting allowed fields in update operations instead of accepting all user-provided data

Applied to files:

  • apps/web/utils/auth.test.ts
📚 Learning: 2025-11-25T14:39:23.326Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:23.326Z
Learning: Applies to app/api/**/*.ts : Use `withAuth` middleware for user-level operations (user settings, API keys, referrals) - provides only `userId` in `request.auth`

Applied to files:

  • apps/web/utils/auth.test.ts
🧬 Code graph analysis (3)
apps/web/utils/auth/cleanup-invalid-tokens.test.ts (1)
apps/web/utils/logger.ts (1)
  • createScopedLogger (18-82)
apps/web/utils/meeting-briefs/recipient-context.test.ts (1)
apps/web/utils/logger.ts (1)
  • createScopedLogger (18-82)
apps/web/utils/auth.test.ts (1)
apps/web/utils/error-messages/index.ts (1)
  • clearUserErrorMessages (56-72)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Baz Reviewer
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: test
  • GitHub Check: Macroscope - Correctness Check
🔇 Additional comments (6)
apps/web/utils/auth/cleanup-invalid-tokens.test.ts (2)

8-9: LGTM! Proper logger setup for tests.

The module-scoped logger using createScopedLogger("test") aligns with the project's logging guidelines for test files.

Based on learnings, this approach is correct for standalone tests that don't run within a middleware chain.


38-63: LGTM! Logger properly threaded through test cases.

The logger is correctly passed to both cleanupInvalidTokens and validated in the addUserErrorMessage expectations. This ensures consistent logging context throughout the error notification flow.

apps/web/utils/auth.test.ts (2)

147-149: LGTM! Appropriate use of partial matching for function parameters.

Using expect.objectContaining({ userId: "user_1" }) allows the test to verify the critical userId parameter while remaining flexible about the logger instance. This is a sensible approach given that clearUserErrorMessages now accepts both userId and logger.


179-181: LGTM! Consistent test assertion pattern.

This test follows the same partial matching approach as the previous test, ensuring consistency across the test suite.

apps/web/utils/meeting-briefs/recipient-context.test.ts (2)

10-12: LGTM! Consistent logger setup across test files.

The module-scoped logger using createScopedLogger("test") follows the same pattern as other test files in this PR, promoting consistency and adherence to the project's logging guidelines.

Based on learnings, this approach correctly uses createScopedLogger for standalone tests.


234-245: LGTM! Logger consistently threaded through all test cases.

All seven test cases in getMeetingContext properly pass the logger parameter, ensuring consistent logging context across the test suite. This thorough update aligns with the PR's objective to thread logger context through error utilities and callers.

Also applies to: 247-302, 304-353, 355-372, 374-414, 416-456, 458-492


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 and usage tips.

@macroscopeapp
Copy link
Contributor

macroscopeapp bot commented Jan 4, 2026

Unify user-fixable error notifications and logging by routing actions and utilities through apps/web/utils/error-messages/index.ts and sending one-time Action Required emails via packages/resend/src/send.tsx

Introduce a logger-threaded error message flow with addUserErrorMessageWithNotification, selective clears via clearSpecificErrorMessages, and email dispatch using sendActionRequiredEmail; update LLM, auth, settings, and Outlook paths to pass logger and trigger notifications.

📍Where to Start

Start with the error message utilities in index.ts, then review the LLM error handler in index.ts and the email sender in send.tsx.


Macroscope summarized 2439bbe.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 6 files

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="apps/web/utils/error-messages/index.ts">

<violation number="1" location="apps/web/utils/error-messages/index.ts:70">
P2: Missing `userId` context in `captureException` call. Other similar functions in this file (`clearSpecificErrorMessages`, `addUserErrorMessageWithNotification`) include userId in the extra context for error tracking. This removal makes debugging harder when errors occur in this function.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment on lines +193 to +215
if (shouldSendEmail) {
try {
const config = errorTypeConfig[errorType];
const unsubscribeToken = await createUnsubscribeToken({
emailAccountId,
});

await sendActionRequiredEmail({
from: env.RESEND_FROM_EMAIL,
to: userEmail,
emailProps: {
baseUrl: env.NEXT_PUBLIC_BASE_URL,
email: userEmail,
unsubscribeToken,
errorType: config.label,
errorMessage,
actionUrl: config.actionUrl,
actionLabel: config.actionLabel,
},
});

newEntry.emailSentAt = new Date().toISOString();
logger.info("Sent action required email", { errorType });
Copy link
Contributor

Choose a reason for hiding this comment

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

When Resend is not configured (sendEmail returns early because resend is null) the try block in addUserErrorMessageWithNotification still reaches line 214 and sets emailSentAt, so the code never retries notifications even though nothing was delivered. Because sendEmail doesn't throw when the API key is missing, we silently skip notifying the user—there is no log/error via the injected logger and no follow-up email. Please either surface the missing Resend configuration or avoid marking emailSentAt until sendActionRequiredEmail actually sends an email so that the failure is observable and the notification is retried.


Finding type: Logical Bugs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 10d93e0 and d29d4b0.

📒 Files selected for processing (1)
  • apps/web/utils/error-messages/index.ts
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/data-fetching.mdc)

**/*.{ts,tsx}: For API GET requests to server, use the swr package
Use result?.serverError with toastError from @/components/Toast for error handling in async operations

**/*.{ts,tsx}: Use wrapper functions for Gmail message operations (get, list, batch, etc.) from @/utils/gmail/message.ts instead of direct API calls
Use wrapper functions for Gmail thread operations from @/utils/gmail/thread.ts instead of direct API calls
Use wrapper functions for Gmail label operations from @/utils/gmail/label.ts instead of direct API calls

**/*.{ts,tsx}: For early access feature flags, create hooks using the naming convention use[FeatureName]Enabled that return a boolean from useFeatureFlagEnabled("flag-key")
For A/B test variant flags, create hooks using the naming convention use[FeatureName]Variant that define variant types, use useFeatureFlagVariantKey() with type casting, and provide a default "control" fallback
Use kebab-case for PostHog feature flag keys (e.g., inbox-cleaner, pricing-options-2)
Always define types for A/B test variant flags (e.g., type PricingVariant = "control" | "variant-a" | "variant-b") and provide type safety through type casting

**/*.{ts,tsx}: Don't use primitive type aliases or misleading types
Don't use empty type parameters in type aliases and interfaces
Don't use this and super in static contexts
Don't use any or unknown as type constraints
Don't use the TypeScript directive @ts-ignore
Don't use TypeScript enums
Don't export imported variables
Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions
Don't use TypeScript namespaces
Don't use non-null assertions with the ! postfix operator
Don't use parameter properties in class constructors
Don't use user-defined types
Use as const instead of literal types and type annotations
Use either T[] or Array<T> consistently
Initialize each enum member value explicitly
Use export type for types
Use `impo...

Files:

  • apps/web/utils/error-messages/index.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/prisma-enum-imports.mdc)

Always import Prisma enums from @/generated/prisma/enums instead of @/generated/prisma/client to avoid Next.js bundling errors in client components

Import Prisma using the project's centralized utility: import prisma from '@/utils/prisma'

Files:

  • apps/web/utils/error-messages/index.ts
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

Import specific lodash functions rather than entire lodash library to minimize bundle size (e.g., import groupBy from 'lodash/groupBy')

apps/web/**/*.{ts,tsx}: Use TypeScript with strict null checks
Do not export types/interfaces that are only used within the same file. Export later if needed

Files:

  • apps/web/utils/error-messages/index.ts
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/security.mdc)

**/*.ts: ALL database queries MUST be scoped to the authenticated user/account by including user/account filtering in WHERE clauses to prevent unauthorized data access
Always validate that resources belong to the authenticated user before performing operations, using ownership checks in WHERE clauses or relationships
Always validate all input parameters for type, format, and length before using them in database queries
Use SafeError for error responses to prevent information disclosure. Generic error messages should not reveal internal IDs, logic, or resource ownership details
Only return necessary fields in API responses using Prisma's select option. Never expose sensitive data such as password hashes, private keys, or system flags
Prevent Insecure Direct Object References (IDOR) by validating resource ownership before operations. All findUnique/findFirst calls MUST include ownership filters
Prevent mass assignment vulnerabilities by explicitly whitelisting allowed fields in update operations instead of accepting all user-provided data
Prevent privilege escalation by never allowing users to modify system fields, ownership fields, or admin-only attributes through user input
All findMany queries MUST be scoped to the user's data by including appropriate WHERE filters to prevent returning data from other users
Use Prisma relationships for access control by leveraging nested where clauses (e.g., emailAccount: { id: emailAccountId }) to validate ownership

Files:

  • apps/web/utils/error-messages/index.ts
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

**/*.{tsx,ts}: Use Shadcn UI and Tailwind for components and styling
Use next/image package for images
For API GET requests to server, use the swr package with hooks like useSWR to fetch data
For text inputs, use the Input component with registerProps for form integration and error handling

Files:

  • apps/web/utils/error-messages/index.ts
**/*.{tsx,ts,css}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

Implement responsive design with Tailwind CSS using a mobile-first approach

Files:

  • apps/web/utils/error-messages/index.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{js,jsx,ts,tsx}: Don't use accessKey attribute on any HTML element
Don't set aria-hidden="true" on focusable elements
Don't add ARIA roles, states, and properties to elements that don't support them
Don't use distracting elements like <marquee> or <blink>
Only use the scope prop on <th> elements
Don't assign non-interactive ARIA roles to interactive HTML elements
Make sure label elements have text content and are associated with an input
Don't assign interactive ARIA roles to non-interactive HTML elements
Don't assign tabIndex to non-interactive HTML elements
Don't use positive integers for tabIndex property
Don't include "image", "picture", or "photo" in img alt prop
Don't use explicit role property that's the same as the implicit/default role
Make static elements with click handlers use a valid role attribute
Always include a title element for SVG elements
Give all elements requiring alt text meaningful information for screen readers
Make sure anchors have content that's accessible to screen readers
Assign tabIndex to non-interactive HTML elements with aria-activedescendant
Include all required ARIA attributes for elements with ARIA roles
Make sure ARIA properties are valid for the element's supported roles
Always include a type attribute for button elements
Make elements with interactive roles and handlers focusable
Give heading elements content that's accessible to screen readers (not hidden with aria-hidden)
Always include a lang attribute on the html element
Always include a title attribute for iframe elements
Accompany onClick with at least one of: onKeyUp, onKeyDown, or onKeyPress
Accompany onMouseOver/onMouseOut with onFocus/onBlur
Include caption tracks for audio and video elements
Use semantic elements instead of role attributes in JSX
Make sure all anchors are valid and navigable
Ensure all ARIA properties (aria-*) are valid
Use valid, non-abstract ARIA roles for elements with ARIA roles
Use valid AR...

Files:

  • apps/web/utils/error-messages/index.ts
!(pages/_document).{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

Don't use the next/head module in pages/_document.js on Next.js projects

Files:

  • apps/web/utils/error-messages/index.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)

**/*.{js,ts,jsx,tsx}: Use lodash utilities for common operations (arrays, objects, strings)
Import specific lodash functions to minimize bundle size (e.g., import groupBy from 'lodash/groupBy')

Files:

  • apps/web/utils/error-messages/index.ts
**/{utils,helpers,lib}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/logging.mdc)

Logger should be passed as a parameter to helper functions instead of creating their own logger instances

Files:

  • apps/web/utils/error-messages/index.ts
apps/web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

apps/web/**/*.{ts,tsx,js,jsx}: Use @/ path aliases for imports from project root
Prefer self-documenting code over comments; use descriptive variable and function names instead of explaining intent with comments
Add helper functions to the bottom of files, not the top
All imports go at the top of files, no mid-file dynamic imports

Files:

  • apps/web/utils/error-messages/index.ts
apps/web/**/*.{ts,tsx,js,jsx,json,css}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

Format code with Prettier

Files:

  • apps/web/utils/error-messages/index.ts
apps/web/**/*.{example,ts,json}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

Add environment variables to .env.example, env.ts, and turbo.json

Files:

  • apps/web/utils/error-messages/index.ts
🧠 Learnings (11)
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : Use descriptive scoped loggers for each LLM feature, log inputs and outputs with appropriate log levels, and include relevant context in log messages

Applied to files:

  • apps/web/utils/error-messages/index.ts
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : LLM feature functions must import from `zod` for schema validation, use `createScopedLogger` from `@/utils/logger`, `chatCompletionObject` and `createGenerateObject` from `@/utils/llms`, and import `EmailAccountWithAI` type from `@/utils/llms/types`

Applied to files:

  • apps/web/utils/error-messages/index.ts
📚 Learning: 2025-11-25T14:39:08.150Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security-audit.mdc:0-0
Timestamp: 2025-11-25T14:39:08.150Z
Learning: Applies to apps/web/app/api/**/*.{ts,tsx} : Use generic error messages instead of revealing internal details; throw `SafeError` instead of exposing user IDs, resource IDs, or system information

Applied to files:

  • apps/web/utils/error-messages/index.ts
📚 Learning: 2025-11-25T14:37:22.660Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/gmail-api.mdc:0-0
Timestamp: 2025-11-25T14:37:22.660Z
Learning: Applies to **/*.{ts,tsx} : Use wrapper functions for Gmail message operations (get, list, batch, etc.) from @/utils/gmail/message.ts instead of direct API calls

Applied to files:

  • apps/web/utils/error-messages/index.ts
📚 Learning: 2025-11-25T14:39:23.326Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:23.326Z
Learning: Applies to app/api/**/*.ts : Use `SafeError` for error responses to prevent information disclosure - provide generic messages (e.g., 'Rule not found' not 'Rule {id} does not exist for user {userId}') without revealing internal IDs or ownership details

Applied to files:

  • apps/web/utils/error-messages/index.ts
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : Use TypeScript types for all LLM function parameters and return values, and define clear interfaces for complex input/output structures

Applied to files:

  • apps/web/utils/error-messages/index.ts
📚 Learning: 2025-11-25T14:39:27.909Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:27.909Z
Learning: Applies to **/app/api/**/*.ts : Maintain consistent error response format across all API routes to avoid information disclosure while providing meaningful error feedback

Applied to files:

  • apps/web/utils/error-messages/index.ts
📚 Learning: 2025-11-25T14:37:22.660Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/gmail-api.mdc:0-0
Timestamp: 2025-11-25T14:37:22.660Z
Learning: Applies to **/*.{ts,tsx} : Use wrapper functions for Gmail label operations from @/utils/gmail/label.ts instead of direct API calls

Applied to files:

  • apps/web/utils/error-messages/index.ts
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : Implement early returns for invalid LLM inputs, use proper error types and logging, implement fallbacks for AI failures, and add retry logic for transient failures using `withRetry`

Applied to files:

  • apps/web/utils/error-messages/index.ts
📚 Learning: 2025-11-25T14:37:22.660Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/gmail-api.mdc:0-0
Timestamp: 2025-11-25T14:37:22.660Z
Learning: Applies to **/*.{ts,tsx} : Use wrapper functions for Gmail thread operations from @/utils/gmail/thread.ts instead of direct API calls

Applied to files:

  • apps/web/utils/error-messages/index.ts
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : User prompts must contain the actual data and context, and should be kept separate from system prompts

Applied to files:

  • apps/web/utils/error-messages/index.ts
🧬 Code graph analysis (1)
apps/web/utils/error-messages/index.ts (5)
apps/web/utils/logger.ts (1)
  • Logger (6-6)
apps/web/utils/error.ts (1)
  • captureException (46-76)
apps/web/utils/unsubscribe.ts (1)
  • createUnsubscribeToken (5-21)
packages/resend/src/send.tsx (1)
  • sendActionRequiredEmail (212-237)
apps/web/env.ts (1)
  • env (17-258)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Baz Reviewer
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: test
  • GitHub Check: Macroscope - Correctness Check
🔇 Additional comments (4)
apps/web/utils/error-messages/index.ts (4)

1-14: LGTM! Clean imports and type extension.

The new imports support the email notification system, and the emailSentAt field properly tracks one-time email delivery. The Logger type integration aligns with the coding guideline to pass loggers as parameters.


28-72: LGTM! Logger parameter threading is correct.

Both functions now accept logger: Logger as a parameter, which aligns with the coding guideline that helper functions should receive loggers rather than create their own instances. The userId context in captureException at line 70 is properly included.


74-110: LGTM! Well-structured selective error clearing.

The function properly clears specific error types with appropriate error handling. The captureException call includes both userId and errorTypes for debugging context, and the early return pattern for missing users is clean.


121-155: LGTM! Type-safe error configuration.

The errorTypeConfig mapping is properly typed to require all ErrorType values, ensuring compile-time validation that no error type is missing from the configuration. The relative URLs will be correctly combined with baseUrl in the email template.

@elie222 elie222 merged commit d056e56 into main Jan 4, 2026
18 checks passed
@elie222 elie222 deleted the fix/unified-error-notifications branch January 4, 2026 08:03
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

Comments