feat(app-studio): report edge provisioning instead of a broken preview#419
Merged
Conversation
In production the preview URL is served through the Gateway edge (cfgate / Cloudflare Tunnel), which takes a minute or more to program DNS and provision the hostname's TLS certificate. The preview path declared Ready as soon as the instance had a status.url — i.e. as soon as the HTTPRoute existed — so the portal iframed a URL whose TLS handshake still fails and the user stared at a broken preview with no explanation. Gate readiness on the edge actually serving the URL: the preview path probes it (real HTTPS request, certificate verification on — an unprovisioned certificate failing the handshake IS the signal; Cloudflare's 52x range counts as not-provisioned, any app-level status counts as served) and keeps answering Ready=false with reason=edge_provisioning and a human message — "being provisioned at the edge (DNS + TLS certificate), usually a minute or two" — until the probe succeeds. The portal already renders the not-ready message and polls, so no frontend change is needed; the assistant's preview tool picks up the same message. Successes are cached per URL for the process lifetime (certificates persist once provisioned), so the probe adds no steady-state latency; failures are re-probed on every poll. The probe is injectable for tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR improves App Studio’s development preview UX by preventing the portal (and assistant tooling) from presenting a “Ready” preview URL until the external edge (DNS + TLS via the Gateway/Cloudflare Tunnel) is actually serving it, avoiding broken iframes during certificate provisioning.
Changes:
- Gate
templateDevelopmentPreviewreadiness on a real, bounded HTTPS probe ofstatus.url, returningreason=edge_provisioningwith a user-facing message until the edge serves. - Add a per-URL, process-lifetime cache so successful edge readiness probes don’t add steady-state latency.
- Add unit tests for probe gating/caching and HTTP status classification.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| providers/app-studio/api/server.go | Adds server fields to support an injectable edge probe and a readiness cache. |
| providers/app-studio/api/project_template.go | Gates preview “Ready” on edge-served URL instead of status.url presence alone. |
| providers/app-studio/api/preview_edge.go | Implements edge probing, caching, and provisioning reason/message constants. |
| providers/app-studio/api/preview_edge_test.go | Adds unit tests for readiness gating/caching and probe classification. |
Comment on lines
+108
to
+110
| if resp.StatusCode >= 520 && resp.StatusCode <= 530 { | ||
| return fmt.Errorf("edge answered %d (origin/tunnel not provisioned)", resp.StatusCode) | ||
| } |
Comment on lines
+87
to
+92
| dead := httptest.NewServer(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})) | ||
| deadURL := dead.URL | ||
| dead.Close() // connection refused from here on | ||
| if err := defaultPreviewEdgeProbe(context.Background(), deadURL); err == nil { | ||
| t.Fatal("transport error must count as not provisioned") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In production the preview URL is served through the Gateway edge (cfgate / Cloudflare Tunnel), which takes a minute or more to program DNS and provision the hostname's TLS certificate. The preview path declared Ready as soon as the instance had a
status.url— i.e. as soon as the HTTPRoute existed — so the portal iframed a URL whose TLS handshake still fails, and the user stared at a broken preview with no explanation of "we're provisioning, please wait".Fix
Gate preview readiness on the edge actually serving the URL:
templateDevelopmentPreviewnow probesstatus.urlbefore answering Ready. Until the probe succeeds it keeps returningready: false, reason: edge_provisioningwith a human message: "Preview is getting ready. The public URL is being provisioned at the edge (DNS + TLS certificate) — this usually takes a minute or two."SetPreviewEdgeProbe) for tests.No frontend change needed: the portal already polls and renders the not-ready
message("Synced project files. "), and the assistant's preview tool passes the same payload through — both now say what's happening instead of handing out a dead URL.Verification
New unit tests pin the gate + cache semantics and the probe classification (app-level 404 = served, 522 = provisioning, transport error = provisioning). Full app-studio
go test ./..., build, vet pass.🤖 Generated with Claude Code