Skip to content

fix: return 503 for service_unavailable build errors#1716

Merged
WcaleNieWolny merged 1 commit intomainfrom
fix/service-unavailable-503
Feb 27, 2026
Merged

fix: return 503 for service_unavailable build errors#1716
WcaleNieWolny merged 1 commit intomainfrom
fix/service-unavailable-503

Conversation

@WcaleNieWolny
Copy link
Contributor

@WcaleNieWolny WcaleNieWolny commented Feb 27, 2026

Summary

  • Replace simpleError('service_unavailable', ...) (HTTP 400) with quickError(503, ...) at 5 call sites in the build request/upload flow
  • Builder availability errors are transient server-side failures, not client errors — 503 is the semantically correct status
  • This enables the CLI's existing retry logic (3 attempts with 1s/3s/5s backoff) to automatically retry these failures

Test plan

  • Verify builder unavailable errors now return HTTP 503
  • Verify CLI retries on 503 responses
  • Verify non-service_unavailable errors (missing_parameter, unauthorized, etc.) still return 400

Summary by CodeRabbit

  • Chores
    • Improved error handling consistency in backend service requests. Error responses are now standardized for certain failure scenarios, enhancing system reliability monitoring.

Builder availability errors (not configured, call failed, error response,
missing upload URL) are transient server-side failures, not client errors.
Returning 503 allows the CLI retry logic to automatically retry these
requests instead of treating them as terminal 400 errors.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/service-unavailable-503

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.

@WcaleNieWolny WcaleNieWolny marked this pull request as ready for review February 27, 2026 05:22
@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adjusts build request/upload error handling so transient “builder unavailable” conditions return HTTP 503 (instead of 400), enabling the CLI’s existing retry behavior for these cases.

Changes:

  • Switched multiple service_unavailable errors in the build request flow from simpleError(...) (400) to quickError(503, ...).
  • Switched the TUS upload proxy “builder not configured” error to return 503.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
supabase/functions/_backend/public/build/request.ts Return 503 for builder configuration/call failures during build job creation.
supabase/functions/_backend/public/build/upload.ts Return 503 when builder config is missing for the TUS proxy upload path.
Comments suppressed due to low confidence (3)

supabase/functions/_backend/public/build/request.ts:205

  • The catch block will also catch the HTTPException thrown by quickError in the non-OK response path (line 189). As a result, the more specific "(builder error)" exception is immediately replaced with the generic "(builder call failed)" error and logs an incorrect "fetch failed" entry. Consider rethrowing HTTPException instances (or otherwise bypassing the catch for already-formed errors) so only actual network/serialization failures hit this catch path.
      throw quickError(503, 'service_unavailable', 'Build service unavailable (builder error)')
    }
  }
  catch (error) {
    cloudlogErr({
      requestId: c.get('requestId'),
      message: 'Builder API fetch failed',
      builder_url: builderUrl,
      error: (error as Error)?.message,
      error_stack: (error as Error)?.stack,
      error_name: (error as Error)?.name,
      org_id,
      app_id,
      platform,
    })
    throw quickError(503, 'service_unavailable', 'Build service unavailable (builder call failed)')
  }

supabase/functions/_backend/public/build/request.ts:133

  • This change alters the HTTP status for service_unavailable build-request failures to 503 (to enable retries), but there doesn't appear to be any test coverage asserting the new 503 behavior for the /build/request flow. Please add/extend tests to assert these service-unavailable scenarios return 503 (and that other validation errors remain 400).
  if (!builderUrl || !builderApiKey) {
    cloudlogErr({
      requestId: c.get('requestId'),
      message: 'Builder API not configured',
      builder_url_configured: !!builderUrl,
      builder_api_key_configured: !!builderApiKey,
    })
    throw quickError(503, 'service_unavailable', 'Build service unavailable (builder not configured)')
  }

supabase/functions/_backend/public/build/upload.ts:37

  • The tusProxy endpoint now returns 503 when the builder is not configured. There doesn't appear to be a test asserting this specific status code for the /build/upload/:jobId TUS proxy path when BUILDER_URL/BUILDER_API_KEY are missing. Adding a test for this would prevent regressions and validate the CLI retry-trigger behavior.
  if (!builderUrl || !builderApiKey) {
    cloudlogErr({
      requestId: c.get('requestId'),
      message: 'Builder not configured for TUS proxy',
      job_id: jobId,
    })
    throw quickError(503, 'service_unavailable', 'Builder service not configured')
  }

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
supabase/functions/_backend/public/build/request.ts (1)

189-204: ⚠️ Potential issue | 🟡 Minor

HTTPException thrown on line 189 will be re-caught and re-wrapped on line 204.

The quickError on line 189 throws an HTTPException, which the catch block on line 192 will intercept. The error is then re-thrown with the message "builder call failed" instead of the intended "builder error". This loses the distinction between "builder returned an error response" vs "network/fetch failure".

This is a pre-existing structural issue, but since this PR focuses on error handling, consider restructuring:

🔧 Proposed fix: Re-throw HTTPException to preserve error context
   catch (error) {
+    // Re-throw if already an HTTPException (from line 189)
+    if (error instanceof HTTPException) {
+      throw error
+    }
     cloudlogErr({
       requestId: c.get('requestId'),
       message: 'Builder API fetch failed',

You'll also need to import HTTPException from hono/http-exception.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@supabase/functions/_backend/public/build/request.ts` around lines 189 - 204,
The catch block is currently intercepting the HTTPException thrown by quickError
in the build response handling and re-wrapping it as a generic "builder call
failed" error, losing original context; update the catch in the function
handling the builder call to detect and re-throw instances of HTTPException
(importing HTTPException from 'hono/http-exception') instead of logging and
converting them, so only non-HTTP errors are logged via cloudlogErr (which uses
c.get('requestId'), builderUrl, org_id, app_id, platform) and then wrapped with
quickError('service_unavailable', 'Build service unavailable (builder call
failed)') — preserve the original HTTPException for builder error responses and
only handle other exceptions in the existing logging/throwing path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@supabase/functions/_backend/public/build/request.ts`:
- Around line 189-204: The catch block is currently intercepting the
HTTPException thrown by quickError in the build response handling and
re-wrapping it as a generic "builder call failed" error, losing original
context; update the catch in the function handling the builder call to detect
and re-throw instances of HTTPException (importing HTTPException from
'hono/http-exception') instead of logging and converting them, so only non-HTTP
errors are logged via cloudlogErr (which uses c.get('requestId'), builderUrl,
org_id, app_id, platform) and then wrapped with
quickError('service_unavailable', 'Build service unavailable (builder call
failed)') — preserve the original HTTPException for builder error responses and
only handle other exceptions in the existing logging/throwing path.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e719357 and 6bc1e16.

📒 Files selected for processing (2)
  • supabase/functions/_backend/public/build/request.ts
  • supabase/functions/_backend/public/build/upload.ts

@sonarqubecloud
Copy link

@WcaleNieWolny WcaleNieWolny merged commit d6910b6 into main Feb 27, 2026
18 checks passed
@WcaleNieWolny WcaleNieWolny deleted the fix/service-unavailable-503 branch February 27, 2026 05:28
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