Skip to content

Fix rate-limit overrides, AI error reports, and the login crash - #190

Merged
Programcode merged 5 commits into
mainfrom
cursor/fix-sentry-and-rate-limits-8245
Oct 22, 2026
Merged

Programcode merged 5 commits into
mainfrom
cursor/fix-sentry-and-rate-limits-8245

Conversation

@Programcode

@Programcode Programcode commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

Fixes JAVASCRIPT-REACT-6
Fixes JAVASCRIPT-REACT-9

Rate-limit overrides

rate_limits lookups ordered by updated_at. Production only has created_at, so PostgREST returned 400 and the client ignored it. Per-account and global daily_requests overrides never applied. Voice uses the same helper.

Lookups now order by created_at. A failed lookup logs a server-side warning without the user id and falls back. The admin limits action uses the same column. New migration supabase/migrations/20261022140000_rate_limits_order_by_created_at.sql replaces get_active_rate_limits to order by created_at, then id. This migration is in the PR and is not applied.

Tests reject any rate_limits query whose order contains updated_at, and cover per-user over global over fallback, plus the logged error.

AI errors (JAVASCRIPT-REACT-6)

Network failures (Failed to fetch, Firefox/Safari network messages, or the browser offline) become AINetworkError. The product event ai_request_failed still fires. Sentry does not. Unknown failures become AIUnknownError and Sentry gets a privacy-safe cause type (name:Constructor), never the message. 402, 403, and timeouts are unchanged. Offline copy is in en, es, and hu.

Brainstorm AIError at 17:08 Budapest (JAVASCRIPT-REACT-7)

Distinct from the network issue. One handled event on /app/brainstorm at 15:08 UTC, release 34fb5856, statusCode 500, durationMs 1882, feature brainstorm. On that release, mapAIError also stamped status 500 when no HTTP status existed, so the Sentry title was AIError: AIError either way.

A body with code: provider_error stays AIProviderError. Any other real 5xx is now AIServerError (still captured, with its status). A failure with no HTTP status is no longer given status 500.

Dead session refetch

getUser() 401 or 403 signs out once with { scope: 'local' }, blocks a restored SIGNED_IN from hydrating again, and RequireAuth sends the tab to /login. REST 401 still refreshes once. Refresh outages use backoff from 1s to 60s. A thrown getUser (outage) keeps the local session. Stub browser sessions now answer GET /auth/v1/user so a render check is not signed out.

406 noise

checkUserBanned and getGlobalPrompt use maybeSingle(). No row still means not banned and a null prompt. Tests check the no-row path and that Accept does not demand application/vnd.pgrst.object+json.

Stripe Deno.core.runMicrotasks()

create-checkout and account imported stripe from esm.sh with ?target=deno, which pulled std@0.177.1 process.nextTick. That calls Deno.core.runMicrotasks() after the response. Checkout sessions were still created.

Shared createEdgeStripe imports npm:stripe@14.10.0 (worker build) and keeps Stripe.createFetchHttpClient(). The same import was in create-portal and stripe-webhook, so those use it too. npm run test:edge passes --node-modules-dir=auto. A test checks the fetch client name and that the Node client throws. Edge Functions are not deployed.

Login crash (JAVASCRIPT-REACT-9)

Unhandled TypeError: (destructured parameter) is undefined on /login, three events, release 34fb5856. The stack is the lazy import of @vercel/analytics/react: Vite resolves a prevented preload error to undefined, and .then(({ Analytics }) => …) throws. The event Sentry returned is Firefox 157 on Linux, timezone Europe/Budapest, zero users. SpeedInsights had the same destructure. A missing analytics chunk now renders nothing instead of taking down the page.

Verification

npm run verify passed locally on this commit: docs check, lint, typecheck, 422 unit tests, 30 collaboration tests, edge tests, build, service-worker check, and 43 desktop Chromium @smoke tests. This is a local pass, not a GitHub Actions result.

Open in Web Open in Cursor 

Summary by CodeRabbit

  • Bug Fixes
    • Improved sign-in reliability by checking restored sessions and signing out when access is rejected.
    • AI requests now show a helpful message when you’re offline and handle network, server, and unexpected errors more clearly.
    • Daily usage limits now reflect the latest applicable rate-limit settings.
    • Missing optional telemetry components and unavailable prompts no longer disrupt loading.
    • Billing and checkout handling better accommodates customer and price records with unspecified deletion status.

Rate-limit lookups ordered by updated_at, which production does not have, so every override was ignored. Order by created_at and log the lookup failure. The new migration is not applied.

Network failures are AINetworkError and stay out of Sentry. Unknown failures are AIUnknownError with a privacy-safe cause type. Other HTTP 5xx responses are AIServerError.

A 401 or 403 from getUser signs out once and stops store reloads. Missing rows use maybeSingle. Edge Stripe uses the npm worker build and the fetch client.

Optional analytics chunks no longer crash /login when a preload resolves to undefined.

Fixes JAVASCRIPT-REACT-6
Fixes JAVASCRIPT-REACT-9

Co-authored-by: Gáborjáni-Szabó Ádám <Programcode@users.noreply.github.com>
@vercel

vercel Bot commented Oct 22, 2026

Copy link
Copy Markdown

Deployment failed for project debate-navigator with the following error:

Resource is limited - try again in 24 hours (more than 100, code: "api-deployments-free-per-day").

Learn More: https://vercel.com/adam-gaborjanis-projects?upgradeToPro=build-rate-limit

Copilot AI balanced review requested due to automatic review settings October 22, 2026 16:04
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between 09faf68 and fba0ed6.

📒 Files selected for processing: 50
  • e2e/helpers/auth.ts
  • package.json
  • src/components/WebTelemetry.tsx
  • src/components/optional-telemetry.ts
  • src/hooks/use-subscription.test.tsx
  • src/hooks/use-subscription.ts
  • src/lib/ai/client.ts
  • src/lib/ai/error-display.ts
  • src/lib/ai/errors.test.ts
  • src/lib/ai/errors.ts
  • src/lib/ai/request-failure.test.ts
  • src/lib/ai/request.ts
  • src/lib/ai/streaming.ts
  • src/lib/observability.ts
  • src/lib/stores/debate-store.ts
  • src/lib/stores/session-store.ts
  • src/lib/stores/settings-store.ts
  • src/lib/stores/sparring-store.ts
  • src/lib/supabase/AuthProvider.tsx
  • src/lib/supabase/client.ts
  • src/lib/supabase/session-expiry.ts
  • src/locales/en.json
  • src/locales/es.json
  • src/locales/hu.json
  • src/test/auth/AuthProvider.behavior.test.tsx
  • src/test/auth/session-expiry.test.ts
  • src/test/components/WebTelemetry.test.tsx
  • supabase/functions/_shared/entitlements.test.ts
  • supabase/functions/_shared/entitlements.ts
  • supabase/functions/_shared/stripe.ts
  • supabase/functions/_shared/stripe_test.ts
  • supabase/functions/account/index.ts
  • supabase/functions/admin/index.ts
  • supabase/functions/ai-stream/handler_test.ts
  • supabase/functions/ai-stream/index_test.ts
  • supabase/functions/ai/debate-context.test.ts
  • supabase/functions/ai/generate-honesty_test.ts
  • supabase/functions/ai/handler-research.test.ts
  • supabase/functions/ai/provider-errors_test.ts
  • supabase/functions/ai/runtime.ts
  • supabase/functions/ai/runtime_prompt_test.ts
  • supabase/functions/ai/stream.test.ts
  • supabase/functions/ai/voice.test.ts
  • supabase/functions/create-checkout/checkout-security.ts
  • supabase/functions/create-checkout/index.ts
  • supabase/functions/create-portal/index.ts
  • supabase/functions/deno.json
  • supabase/functions/stripe-webhook/index.ts
  • supabase/functions/voice/index_test.ts
  • supabase/migrations/20261022180000_rate_limits_order_by_created_at.sql

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

The PR updates AI error handling, session restoration, rate-limit queries, Stripe Edge client setup, optional telemetry loading, and Supabase lookups that can return no rows.

Changes: AI error handling

Layer / File(s) Summary
Classify and map AI errors
src/lib/ai/errors.ts, src/lib/ai/client.ts, src/lib/ai/errors.test.ts
AI error handling now distinguishes network, server, and unknown failures. The client re-exports the new error types and helpers.
Apply classifications to requests and streams
src/lib/ai/request.ts, src/lib/ai/streaming.ts, src/lib/observability.ts, src/lib/ai/request-failure.test.ts
Request and streaming paths report and throw classified errors. Observability accepts the new error names, and tests cover network, unknown, HTTP, and timeout failures.
Display offline errors
src/lib/ai/error-display.ts, src/locales/*.json
The error display returns a localized offline message for network errors. English, Spanish, and Hungarian locale files add the offline translation.

Session restoration and expiry

Layer / File(s) Summary
Track session expiry and retries
src/lib/supabase/session-expiry.ts, src/lib/supabase/client.ts, src/test/auth/session-expiry.test.ts
Session checks handle rejected user lookups, retry delays, and dead-session state. The fetch wrapper identifies user-lookup requests.
Gate restored sessions and hydration
src/lib/supabase/AuthProvider.tsx, src/lib/stores/*, src/test/auth/AuthProvider.behavior.test.tsx, e2e/helpers/auth.ts
AuthProvider confirms restored sessions before installing them or hydrating stores. Store hydration stops when restoration is blocked. Tests cover rejected lookups, and the E2E stub returns a user for GET requests.

Rate-limit lookup updates

Layer / File(s) Summary
Read active rate limits
supabase/migrations/20261022180000_rate_limits_order_by_created_at.sql, supabase/functions/_shared/entitlements.ts, supabase/functions/admin/index.ts, supabase/functions/_shared/entitlements.test.ts
The new admin RPC selects the newest rate-limit row per user and limit type. Entitlement and admin queries use created_at and retain fallback behavior.
Update rate-limit consumers and checks
src/hooks/use-subscription.ts, src/hooks/use-subscription.test.tsx, supabase/functions/ai*/..., supabase/functions/voice/index_test.ts
The subscription hook orders rate-limit rows by created_at and logs lookup errors. Edge-function test mocks reject requests ordered by updated_at.

Stripe Edge client setup

Layer / File(s) Summary
Define shared Edge Stripe setup
supabase/functions/_shared/stripe.ts, supabase/functions/_shared/stripe_test.ts, supabase/functions/deno.json, package.json
The shared Stripe module adds createEdgeStripe with fetch transport and optional API URL settings. Deno configuration and the edge test script use automatic Node modules handling.
Use the shared client in billing functions
supabase/functions/account/index.ts, supabase/functions/create-checkout/*, supabase/functions/create-portal/index.ts, supabase/functions/stripe-webhook/index.ts
The billing functions use the shared Stripe client. Checkout customer and price checks treat only true as deleted.

Optional telemetry loading

Layer / File(s) Summary
Load optional telemetry components
src/components/optional-telemetry.ts, src/components/WebTelemetry.tsx, src/test/components/WebTelemetry.test.tsx
WebTelemetry loads Analytics and SpeedInsights through a helper. Missing exports and rejected loads resolve to a null-rendering fallback.

Optional Supabase row handling

Layer / File(s) Summary
Allow missing prompt rows
supabase/functions/ai/runtime.ts, supabase/functions/ai/runtime_prompt_test.ts
Both global prompt queries use maybeSingle(). Tests verify that an empty result returns null.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AuthProvider
  participant SupabaseClient
  participant SessionExpiry
  participant StoreHydration
  AuthProvider->>SupabaseClient: getUser for restored access token
  SupabaseClient->>SessionExpiry: report rejected user lookup
  SessionExpiry->>AuthProvider: confirm or reject restored session
  AuthProvider->>StoreHydration: hydrate after confirmation
Loading
sequenceDiagram
  participant AIRequest
  participant AIErrorMapper
  participant AIObservability
  AIRequest->>AIErrorMapper: map request failure
  AIErrorMapper->>AIObservability: provide classification and cause type
Loading
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Essentials by visiting https://app.coderabbit.ai/settings/billing.

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

Copilot AI left a comment

Copy link
Copy Markdown

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.

@Programcode
Programcode merged commit ce3836e into main Oct 22, 2026
3 of 13 checks passed
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.

3 participants