mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-07-10 00:58:01 +00:00
## Summary
Account preconditions (sign-in / subscription / credits) on running a
workflow now open their modal directly and stay out of the error panel +
error count — previously `subscription_required` fell through to a red
"1 ERROR — Subscription required to queue workflows" banner. This covers
**both** paths: the `execution_error` websocket event and the `POST
/prompt` 402 queue paywall (`{ type: "PAYMENT_REQUIRED", message:
"Subscription required to queue workflows" }`), which is the exact
payload reported in #12840.
## Changes
- **What**: `execution_error` is classified by a pure
`accountPreconditionRouting` resolver (precedence sign-in > subscription
> credits) and routed to the existing modal via
`useAccountPreconditionDialog`; `executionStore` returns early for
preconditions so they never populate `lastExecutionError` /
`lastPromptError` / `lastNodeErrors` → fully excluded from the panel and
`totalErrorCount`. Runtime credit error at a node → credits modal (out
of panel; can name the node).
- **Queue paywall**: the `queuePrompt` catch resolves the same
precondition from the `POST /prompt` 402 response and opens the modal,
short-circuiting before `lastPromptError`, so the queue paywall stays
out of the panel too. The runtime matcher learns the `"Subscription
required to queue workflows"` message.
- **Breaking**: none.
## Before / After
Free-tier queue paywall (`POST /prompt` → 402) on a cloud build:
**Before** — raw `Subscription required to queue workflows` surfaced in
the error panel (no actionable upgrade):
<img width="1600" height="873" alt="before-error-panel"
src="https://github.com/user-attachments/assets/1b76b742-16bf-47e3-9245-17e35f8f1e70"
/>
**After** — clean subscription modal opens; nothing in the error panel
or error count:
<img width="1600" height="873" alt="after-subscription-modal"
src="https://github.com/user-attachments/assets/13d238cb-20bf-4795-a530-5abcf9968dc7"
/>
## Review Focus
- **Routing-only — the run button is intentionally untouched.** The
original AC#3 ("no Subscribe-to-Run button") is superseded by the FE-978
run-lock decision (pre-emptive role-aware lock, Figma 3253-18671).
Complements #12786 (FE-978 run-lock); disjoint file sets.
- Tests: `accountPreconditionRouting` / `useAccountPreconditionDialog` /
`executionStore` — each precondition routes to its modal and is excluded
from the panel/count; precedence resolves on co-occurrence. Plus
Playwright `browser_tests/tests/subscriptionPaywallError.spec.ts` — the
queue paywall (402) stays out of the error panel, with a control
asserting ordinary queue errors still surface. typecheck / oxlint /
eslint / stylelint / oxfmt / knip clean.
Fixes FE-878
Fixes #12840
69 lines
2.2 KiB
TypeScript
69 lines
2.2 KiB
TypeScript
import type { Page } from '@playwright/test'
|
|
import { expect } from '@playwright/test'
|
|
|
|
import type { PromptResponse } from '@/schemas/apiSchema'
|
|
|
|
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
|
|
import { TestIds } from '@e2e/fixtures/selectors'
|
|
|
|
// Regression for #12840: a free-tier paywall on queue (`POST /prompt` 402 with
|
|
// `{ error: { type: 'PAYMENT_REQUIRED', message: 'Subscription required to
|
|
// queue workflows' } }`) is an account precondition. It must open its own modal
|
|
// and stay out of the error panel, instead of surfacing the raw backend string
|
|
// with non-actionable Find-on-GitHub / Copy actions.
|
|
test.describe('Subscription paywall on queue', { tag: '@ui' }, () => {
|
|
test.beforeEach(async ({ comfyPage }) => {
|
|
await comfyPage.settings.setSetting(
|
|
'Comfy.RightSidePanel.ShowErrorsTab',
|
|
true
|
|
)
|
|
})
|
|
|
|
async function mockQueueError(page: Page, error: PromptResponse['error']) {
|
|
const body: PromptResponse = { node_errors: {}, error }
|
|
await page.route('**/api/prompt', async (route) => {
|
|
await route.fulfill({
|
|
status: 402,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify(body)
|
|
})
|
|
})
|
|
}
|
|
|
|
test('keeps the subscription paywall out of the error panel', async ({
|
|
comfyPage
|
|
}) => {
|
|
await mockQueueError(comfyPage.page, {
|
|
type: 'PAYMENT_REQUIRED',
|
|
message: 'Subscription required to queue workflows',
|
|
details: ''
|
|
})
|
|
|
|
const queued = comfyPage.page.waitForResponse('**/api/prompt')
|
|
await comfyPage.actionbar.queueButton.primaryButton.click()
|
|
await queued
|
|
|
|
await expect(
|
|
comfyPage.page.getByTestId(TestIds.dialogs.errorOverlay)
|
|
).toBeHidden()
|
|
})
|
|
|
|
test('still surfaces ordinary queue errors in the error panel', async ({
|
|
comfyPage
|
|
}) => {
|
|
await mockQueueError(comfyPage.page, {
|
|
type: 'server_error',
|
|
message: 'The server exploded',
|
|
details: ''
|
|
})
|
|
|
|
const queued = comfyPage.page.waitForResponse('**/api/prompt')
|
|
await comfyPage.actionbar.queueButton.primaryButton.click()
|
|
await queued
|
|
|
|
await expect(
|
|
comfyPage.page.getByTestId(TestIds.dialogs.errorOverlay)
|
|
).toBeVisible()
|
|
})
|
|
})
|