Skip to content

fix(backend): harden manifest size processing#2293

Merged
riderx merged 6 commits into
mainfrom
codex/fix-backfill-prod-target
May 20, 2026
Merged

fix(backend): harden manifest size processing#2293
riderx merged 6 commits into
mainfrom
codex/fix-backfill-prod-target

Conversation

@riderx
Copy link
Copy Markdown
Member

@riderx riderx commented May 18, 2026

Summary (AI generated)

  • Default scripts/backfill_manifest_file_sizes.mjs to the production env target and refuse local Postgres URLs unless --target=local is explicit.
  • Process on_manifest_create queue messages directly inside the queue consumer instead of doing one HTTP self-call per manifest row.
  • Make queue processing per-message resilient: one thrown handler/fetch error no longer aborts the full batch, successful messages still delete, and failures keep exact status/error metadata for retries and alerts.
  • Stabilize tests/app-error-cases.test.ts by using the existing retrying fetch helper for transient Edge socket closes.

Motivation (AI generated)

The production failure was not the CLI-provided size. Manifest rows were inserted with file_size = 0, then the queue consumer attempted many internal trigger HTTP calls. A transport timeout rejected the batch-level Promise.all, so some files got updated and the rest stayed at zero until the queue exhausted its 5 reads and archived them. The previous logs hid the exact per-file cause because the batch aborted before recording each result.

Business Impact (AI generated)

New bundles should stop drifting into partial metadata not found states. Existing bad rows can be repaired with the production-safe backfill script after deploy, without accidentally targeting local Supabase.

Test Plan (AI generated)

  • bun test tests/queue-consumer-message-shape.unit.test.ts
  • bun test tests/backend-alert-resilience.unit.test.ts -t manifest
  • bun lint:backend
  • bun lint
  • bun typecheck
  • git diff --check
  • Commit hook: bun run cli:build && vue-tsc --noEmit
  • GitHub Actions: Run tests passed on PR and push workflows after rerunning the transient upstream-response failure.
  • GitHub Actions: Playwright, dead-code, CodeQL, SonarCloud, Socket, DeepSec, and CodSpeed checks passed.

Summary by CodeRabbit

  • New Features

    • Backfill script can target prod or local environments and records the selected target in reports.
    • Queue failure reports now include per-message timing and target URL details.
  • Bug Fixes

    • More robust queue processing: HTTP timeouts, safer cleanup, and clearer error propagation for retries.
  • Chores

    • Refactored queue dispatch for clearer flow.
    • Tests updated for more reliable HTTP interactions and added queue-message compatibility tests.

Review Change Stack

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2d1bf97d-df6e-402e-a816-d2ae8f3c032e

📥 Commits

Reviewing files that changed from the base of the PR and between 4172d8d and 2e57c36.

📒 Files selected for processing (1)
  • supabase/functions/_backend/triggers/queue_consumer.ts

📝 Walkthrough

Walkthrough

Adds a --target prod|local flag to the backfill script with target-aware dotenv/DB loading and safety checks; refactors queue consumer to centralize message processing, HTTP timeout/error normalization, and manifest dispatch (exports updateManifestSize); updates tests to use fetchWithRetry and adds queue-conversion tests.

Changes

Backfill script: target-aware env and DB

Layer / File(s) Summary
Target parsing and dotenv load
scripts/backfill_manifest_file_sizes.mjs
Use programmatic dotenv.parse, parse --target/--local, select and merge dotenv files into process.env.
DB URL helpers and safety
scripts/backfill_manifest_file_sizes.mjs
Add getDatabaseUrl/isLocalDatabaseUrl/getSafeDatabaseUrl and describeDatabaseUrl; throw when prod targets a local DB.
CLI help, connection, and report
scripts/backfill_manifest_file_sizes.mjs
Document --target/--local, resolve safe DB URL, log selected target/host, configure pg.Pool SSL per target, and include target in the output report.

Queue consumer and manifest dispatch

Layer / File(s) Summary
Imports, constants, message types
supabase/functions/_backend/triggers/queue_consumer.ts, supabase/functions/_backend/triggers/on_manifest_create.ts
Add serializeError import, QUEUE_HTTP_TIMEOUT_MS, ProcessedQueueMessage, and QueueLogMetadata; import/export updateManifestSize.
processQueueMessage and helpers
supabase/functions/_backend/triggers/queue_consumer.ts, supabase/functions/_backend/triggers/on_manifest_create.ts
Add resolveFunctionUrl, queueFailureResponse, httpExceptionToQueueResponse, getManifestRecordFromQueueBody, dispatchQueueMessage (uses exported updateManifestSize), and processQueueMessage to centralize per-message HTTP/dispatch logic.
Integration, cleanup, and reporting
supabase/functions/_backend/triggers/queue_consumer.ts
Replace inline per-message mapper with processQueueMessage, wrap mass_edit_queue_messages_cf_ids persistence in try/catch with logging, and add duration_ms/target_url to failureDetails and Discord embeds.
HTTP helper timeout and error normalization
supabase/functions/_backend/triggers/queue_consumer.ts
Change http_post_helper to accept/derive targetUrl, use AbortController with timeout, pass fetch signal, and serialize/rethrow as simpleError('queue_http_post_failed', ...).
Expose test utilities
supabase/functions/_backend/triggers/queue_consumer.ts
Export httpExceptionToQueueResponse, queueFailureResponse, and resolveFunctionUrl via __queueConsumerTestUtils__.

Tests

Layer / File(s) Summary
App error-case tests: retry-capable fetch
tests/app-error-cases.test.ts
Update imports to include fetchWithRetry and replace direct fetch calls with fetchWithRetry for setup, teardown, and all /app error-case requests.
Queue consumer unit tests
tests/queue-consumer-message-shape.unit.test.ts
Add HTTPException import and two concurrent tests asserting queueFailureResponse and httpExceptionToQueueResponse conversion behaviors for retryable and preserved HTTP errors.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Cap-go/capgo#2292: Modifies the same queue consumer/http_post_helper and target/error propagation points.

Poem

🐰 I hop through envs and read each line,
Prod or local — the flags define.
I time each message, guard each post,
Preserve the errors we care about most.
A tidy trail of logs — hop, file, and sign.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: hardening manifest size processing through improved error handling and safety.
Description check ✅ Passed The description is comprehensive with Summary, Motivation, Business Impact, and Test Plan sections; all required template sections are present and well-documented.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-backfill-prod-target

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

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq Bot commented May 18, 2026

Merging this PR will not alter performance

✅ 43 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing codex/fix-backfill-prod-target (2e57c36) with main (7712cd5)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/backfill_manifest_file_sizes.mjs`:
- Around line 58-81: getTarget() currently builds envPaths so that '../.env' is
loaded before the prod-specific file, causing generic DB keys in process.env to
outrank prod-only keys; update the logic so the prod branch does not load the
generic '../.env' (or at minimum loads the prod-specific file last/solely)
and/or change getDatabaseUrl() to resolve against a passed-in env object parsed
from the selected envPaths instead of reading merged process.env; locate and
change the envPaths construction and the call sites of getDatabaseUrl() so the
DB URL is derived only from the intended target's env file(s) (symbols:
getTarget, envPaths, getDatabaseUrl).
- Around line 102-108: The isLocalDatabaseUrl function fails to recognize
bracketed IPv6 loopback hosts because new URL returns '[::1]'; update
isLocalDatabaseUrl to normalize the hostname by stripping surrounding square
brackets (if hostname startsWith('[') and endsWith(']') then hostname =
hostname.slice(1, -1)) before checking against the local host list, and also
extend the catch fallback to look for both '::1' and '[::1]' in the raw
databaseUrl string; this ensures bracketed IPv6 literals are treated as local.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 55375c12-d3e3-43c0-80b2-9f9beec0eb35

📥 Commits

Reviewing files that changed from the base of the PR and between e625a1f and 6b38ab8.

📒 Files selected for processing (1)
  • scripts/backfill_manifest_file_sizes.mjs

Comment thread scripts/backfill_manifest_file_sizes.mjs
Comment thread scripts/backfill_manifest_file_sizes.mjs Outdated
@riderx riderx marked this pull request as draft May 20, 2026 08:42
@riderx riderx changed the title fix(script): default manifest backfill to prod env fix(backend): harden manifest size processing May 20, 2026
@riderx riderx marked this pull request as ready for review May 20, 2026 10:18
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
supabase/functions/_backend/triggers/queue_consumer.ts (1)

240-251: 💤 Low value

Extract nested ternary for readability.

The nested ternary at lines 243-245 is hard to follow. Consider extracting the message resolution to a separate variable.

♻️ Proposed refactor
   if (cause && typeof cause === 'object' && 'error' in cause) {
     const causeData = cause as {
       error?: unknown
       message?: unknown
       moreInfo?: unknown
     }
+    const errorMessage = typeof causeData.message === 'string'
+      ? causeData.message
+      : typeof maybeException.message === 'string'
+        ? maybeException.message
+        : 'Queue handler failed'
     return queueFailureResponse(
       typeof causeData.error === 'string' ? causeData.error : 'http_exception',
-      typeof causeData.message === 'string'
-        ? causeData.message
-        : typeof maybeException.message === 'string'
-          ? maybeException.message
-          : 'Queue handler failed',
+      errorMessage,
       causeData.moreInfo && typeof causeData.moreInfo === 'object'
         ? causeData.moreInfo as Record<string, unknown>
         : {},
       maybeException.status,
     )
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@supabase/functions/_backend/triggers/queue_consumer.ts` around lines 240 -
251, The nested ternary used to compute the error message (checking
causeData.message and maybeException.message) is hard to read; extract that
logic into a clearly named local variable (e.g., resolvedMessage or
messageToLog) before the call that currently inlines it, using the same type
checks (typeof causeData.message === 'string' ? causeData.message : typeof
maybeException.message === 'string' ? maybeException.message : 'Queue handler
failed'), then replace the nested ternary in the argument list with that
variable; keep the existing symbols (causeData, maybeException) and ensure the
variable is used where the current ternary result is passed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@supabase/functions/_backend/triggers/queue_consumer.ts`:
- Around line 240-251: The nested ternary used to compute the error message
(checking causeData.message and maybeException.message) is hard to read; extract
that logic into a clearly named local variable (e.g., resolvedMessage or
messageToLog) before the call that currently inlines it, using the same type
checks (typeof causeData.message === 'string' ? causeData.message : typeof
maybeException.message === 'string' ? maybeException.message : 'Queue handler
failed'), then replace the nested ternary in the argument list with that
variable; keep the existing symbols (causeData, maybeException) and ensure the
variable is used where the current ternary result is passed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2a869fad-25e9-42a0-a06a-8b86ff3de3e2

📥 Commits

Reviewing files that changed from the base of the PR and between d6e50ec and 4172d8d.

📒 Files selected for processing (4)
  • supabase/functions/_backend/triggers/on_manifest_create.ts
  • supabase/functions/_backend/triggers/queue_consumer.ts
  • tests/app-error-cases.test.ts
  • tests/queue-consumer-message-shape.unit.test.ts

@sonarqubecloud
Copy link
Copy Markdown

@riderx riderx merged commit 7b481de into main May 20, 2026
42 checks passed
@riderx riderx deleted the codex/fix-backfill-prod-target branch May 20, 2026 13:37
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