refactor: share cloud HTTPError/URLError envelope handler across workflow + jobs (BE-3266)#524
refactor: share cloud HTTPError/URLError envelope handler across workflow + jobs (BE-3266)#524mattmillerai wants to merge 2 commits into
Conversation
…flow + jobs (BE-3266) Promote workflow.py's _handle_cloud_http_error to a shared comfy_cli/command/_cloud_errors.helper, parameterized on the 404 error code/message/hint, the id label, and the operation string. workflow.py's public wrapper and jobs.py _cloud_cancel both route through it. This closes a user-visible drift: jobs cloud-cancel previously mapped 401/403 to a generic cloud_http_error, so an expired session yielded no actionable code. It now surfaces cloud_unauthorized with a `comfy cloud login` hint, matching workflow. Adds a regression test. models/search.py's three branches differ deliberately (per BE-2143) and are left untouched.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 32 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
🔍 Cursor Review — Consolidated panel
Triggered by @mattmillerai.
Found 2 finding(s).
| Severity | Count |
|---|---|
| 🟡 Medium | 1 |
| 🟢 Low | 1 |
Panel: 6/8 reviewers contributed findings.
Reviewers that did not contribute: kimi-k2.5:adversarial (empty), kimi-k2.5:edge-case (empty)
…3266) Cursor panel findings on the shared envelope handler: - `e.read()` was uncapped and eager. `base_url` is env-configurable, so a hostile/misbehaving endpoint could OOM the CLI, and a reset stream raised *before* any `renderer.error` fired — turning the structured envelope the helper exists to emit into an unhandled traceback. The read is now capped at 1000 bytes (matching the prior `[:1000]` truncation exactly), best-effort (a failed read degrades to an empty body), and skipped entirely on the 404 branch that discards it. - 401/403 hardcoded the `comfy cloud login` hint and dropped the server body and resource id from `details` — a regression for jobs, which surfaced both via the generic branch before unification. A 403 is not unambiguously an auth failure (forbidden resource, quota, already-finished job), so it now keeps the server's explanation and gets a hint that doesn't assert re-login as the fix. 401 is unchanged. `details` is free-form in error.json, so the added keys are additive.
CI status: the
|
|
🤖 The reviews loop filed Linear follow-up ticket(s) for review thread(s) deferred as out of scope for this PR:
|
Both CI failures are now owned by dedicated PRs — nothing left to fix on this branchRe-checked this PR end-to-end. No merge conflict (
Neither is caused by this diff, and I deliberately did not duplicate either fix here — folding an unrelated Verified locally with the unrelated breaks isolated ( Self-review of the diff turned up no regressions. All four |
ELI-5
When
comfy workflow ...orcomfy jobs cancel ...talks to Comfy Cloud and the request fails, the CLI turns the failure into a tidy, structured error with a code and a hint. Two files were doing that translation with their own near-identical copies of the same code — and the copies had quietly drifted apart.workflowknew that a 401/403 means "your login expired, runcomfy cloud login", butjobs canceldidn't: it just said "generic cloud error." This PR pulls the shared translation into one helper both call, so they can't drift again, andjobs cancelnow gives the same actionable "please re-login" message.What changed
comfy_cli/command/_cloud_errors.py—handle_cloud_http_error(...), the single source of truth for mapping a cloudHTTPError/URLError/OSErrorto a structured envelope. Parameterized on the 404 code/message/hint, the id label (workflow_idvsprompt_id), and the operation string; everything else (body truncation, 401/403 →cloud_unauthorized, genericcloud_http_error, network hint) is shared.workflow.py—_handle_cloud_http_errorbecomes a thin wrapper supplying theworkflow-specific 404 envelope. All five existing call sites are unchanged and keep their exact prior behavior.jobs.py—_cloud_cancelroutes itsexceptthrough the shared helper instead of its own hand-rolled copy.jobs cancelnow surfacescloud_unauthorized.Behavior change (intentional, per the ticket)
jobs cloud-cancelpreviously mapped 401/403 → genericcloud_http_error; it now maps them tocloud_unauthorizedwith acomfy cloud loginhint, matchingworkflow. This is the "small behavior change" the ticket calls out. Two additive, harmless detail changes fall out of unifying the generic-cloud_http_errorshape: the generic error'sdetailsnow also carries the resource id (workflow_id/prompt_id) andoperation, and the jobs generic message isHTTP <code> during cancel(wasHTTP <code> cancelling <id>).Out of scope
models/search.py's three URLError/OSError branches differ deliberately (distinct error-code routing + hints, and a docstring from BE-2143 recording the decision not to unify them) — left untouched, per the ticket.Judgment calls
tests/comfy_cli/command/test_jobs.py; the actual jobs test file istests/comfy_cli/jobs/test_jobs.py— updated the real one.comfy_cli/command/_cloud_errors.py) rather thancomfy_cli/http.pysince it depends on the renderer +typer.Exit(both command-layer concerns).Negative-claim falsification
N/A — this change adds an actionable capability (the
cloud_unauthorizedre-login guidance forjobs cancel) rather than denying one; no dead-end/throw path or "not supported" string is introduced.Testing
ruff format+ruff checkclean on all touched files.