Skip to content

feat: support new quote api errors#7609

Merged
shoom3301 merged 25 commits into
developfrom
feat/new-quote-errors-1
Jun 15, 2026
Merged

feat: support new quote api errors#7609
shoom3301 merged 25 commits into
developfrom
feat/new-quote-errors-1

Conversation

@shoom3301

@shoom3301 shoom3301 commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Initially, this PR goal is to support and display the new /quote API errors added in cowprotocol/services#4268.

Changes

  • Replaced the legacy error mapping with direct passthrough. QuoteApiErrorCodes now lists the full set of new API codes (NoLiquidity, SellAmountDoesNotCoverFee, TokenTemporarilySuspended,
    TradingOutsideAllowedWindow, CustomSolverError, etc.). The old operator→quote error mapper (mapOperatorErrorToQuoteError) and the legacy codes it produced (FeeExceedsFrom, ZeroPrice,
    TransferEthToContract, UNHANDLED_ERROR enum member) are removed — QuoteApiError is now constructed straight from the API error body.
  • New type guard getIsQuoteApiTypedError() for quote API errors; getIsOrderBookTypedError() is now properly typed (unknown instead of any).
  • Unhandled errors (e.g. network failures) construct QuoteApiError from the raw error string: the original error is kept in message (for logging/Sentry), while description carries the generic user-facing copy.
  • Error display improvements:
    • Each known error code maps to a friendly, translated label in the trade form button (getQuoteErrorTexts() is now a Partial record).
    • Codes without a dedicated label fall back to the default "Error loading price. Try again later." copy instead of leaking raw backend text into the button.
    • The backend error description is surfaced in a help tooltip next to the error label, so users/support can still see the underlying reason.
  • Sentry: expanded SENTRY_IGNORED_QUOTE_ERRORS with errors that are expected to happen regularly (InsufficientLiquidity, SellAmountDoesNotCoverFee, TokenTemporarilySuspended,
    TradingOutsideAllowedWindow, UnsupportedToken).

To Test

  1. Open the Swap form and trigger quote errors:
  • Trade a token pair with no liquidity → "Insufficient liquidity for this trade" / "Token pair selected has insufficient liquidity" shown in the disabled button
  • Enter a sell amount smaller than the fee → "The selling amount for the order is lower than the fee"; the network-costs banner still shows (SwapWidget SellAmountDoesNotCoverFee handling)
  • Trade an unsupported token → unsupported token button shown
  • Kill the network connection / make the quote request fail → disabled button with "Error loading price. Try again later."
  1. Error details:
  • For an error without a dedicated label, the button shows the default copy and a tooltip with the backend description
  • Quote errors render identically in Swap, Limit, and TWAP forms
Screenshot 2026-06-05 at 16 21 51

You can mock the API response executing the script in the browser console (no need to refresh page after, just change sell amount):

(function() {
    const originalFetch = window.fetch;

window.fetch = async (...args) => {
  if (args[0].includes('/api/v1/quote')) {
    return new Response(
      JSON.stringify({
    "errorType": "CustomSolverError",
    "description": "My custom message"
}),
      {
        status: 400,
        statusText: 'Bad Request',
        headers: {
          'Content-Type': 'application/json',
        },
      }
    );
  }

  return originalFetch(...args);
};
})()

With that you should see:
image

Summary by CodeRabbit

  • New Features

    • Extended support for additional error scenarios including app data validation, token suspension, and trading window restrictions.
  • Bug Fixes

    • Improved error handling and display logic for quote-related failures.
    • Updated fee-related error detection mechanism.
  • Localization

    • Added and refined error message translations for better user guidance on trading issues.

@vercel

vercel Bot commented Jun 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cowfi Ready Ready Preview Jun 15, 2026 11:46am
explorer-dev Ready Ready Preview Jun 15, 2026 11:46am
storybook Ready Ready Preview Jun 15, 2026 11:46am
swap-dev Ready Ready Preview Jun 15, 2026 11:46am
widget-configurator Ready Ready Preview Jun 15, 2026 11:46am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
cosmos Ignored Ignored Jun 15, 2026 11:46am
sdk-tools Ignored Ignored Preview Jun 15, 2026 11:46am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@shoom3301, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 7 minutes and 43 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 95d61d81-4a06-43c1-9f15-b3f364b74b96

📥 Commits

Reviewing files that changed from the base of the PR and between dc6ffbb and da5625a.

📒 Files selected for processing (3)
  • apps/cowswap-frontend/src/api/cowProtocol/errors/QuoteError.ts
  • apps/cowswap-frontend/src/api/cowProtocol/getIsOrderBookTypedError.ts
  • apps/cowswap-frontend/src/modules/tradeFormValidation/pure/QuoteApiErrorButton.pure.tsx

Walkthrough

Refactors the quote API error model by replacing the legacy operator-error mapping with a simplified QuoteApiError class and an updated QuoteApiErrorCodes enum aligned to backend error types. Adds a getIsQuoteApiTypedError type guard, rewires parseError in fetchAndProcessQuote, updates UI error button rendering and error-code-to-text mappings, adds corresponding translations, and adjusts tests.

Changes

Quote API Error Model Refactor and UI Wiring

Layer / File(s) Summary
QuoteApiError model and type guard contracts
src/api/cowProtocol/errors/QuoteError.ts, src/api/cowProtocol/getIsOrderBookTypedError.ts
QuoteApiErrorCodes enum is rewritten with new backend error codes; QuoteApiError constructor gains a string overload with UNHANDLED_ERROR_CODE sentinel; mapOperatorErrorToQuoteError, isValidQuoteError, and QuoteApiErrorDetails are removed. QuoteApiTypedError alias and getIsQuoteApiTypedError type guard are added; getIsOrderBookTypedError parameter tightened from any to unknown.
fetchAndProcessQuote error parsing
src/modules/tradeQuote/services/fetchAndProcessQuote.ts, src/modules/tradeQuote/services/fetchAndProcessQuote.test.ts
parseError now uses getIsQuoteApiTypedError to detect typed errors and constructs QuoteApiError from error.body; untyped fallback constructs QuoteApiError(String(error)). Tests replace mocks for the old order-book guard and mapOperatorErrorToQuoteError with mockGetQuoteApiTypedError.
Quote error UI rendering and code-to-text mapping
src/.../QuoteApiErrorButton.pure.tsx, src/.../QuoteErrorsButton/quoteErrors.utils.ts, src/modules/swap/containers/SwapWidget/index.tsx, src/.../useTokenCustomTradeError.ts
QuoteApiErrorButton renders UNHANDLED_ERROR as a disabled button with DEFAULT_ERROR_TEXT and uses nullish coalescing for error text fallback. getQuoteErrorTexts returns a Partial mapping with updated entries for metadata, validity, liquidity, fee, and token suspension codes. isFeeExceedsError now matches SellAmountDoesNotCoverFee. isValidQuoteError is inlined as an instanceof QuoteApiError check.
en-US translations for new quote error codes
src/locales/en-US.po
Adds active translation strings for the new quote error codes (metadata invalid, validity too long, insufficient liquidity, token suspended, time-window restriction, no liquidity) and deactivates obsolete punctuated/native-currency entries.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • cowprotocol/cowswap#7608: Directly modifies the same QuoteError.ts file, reworking QuoteApiError model and typing in overlapping ways.
  • cowprotocol/cowswap#7145: Modifies fetchAndProcessQuote.ts's parseError flow and typed quote API error handling paths that this PR also rewrites.

Suggested reviewers

  • limitofzero
  • fairlighteth
  • elena-zh

Poem

🐇 Hoppity-hop through the error codes new,
The old FeeExceedsFrom bid us adieu.
SellAmountDoesNotCoverFee takes its place,
UNHANDLED_ERROR_CODE shows its face.
No more mapOperatorError to roam —
A cleaner quote model, the rabbit hops home! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 'feat: support new quote api errors' directly and clearly summarizes the main change—implementation of support for new quote API error codes introduced in the services repository.
Description check ✅ Passed The description provides a clear summary, detailed changes section, comprehensive testing steps with checkboxes, screenshots, and a console script for mocking API responses. It follows the template structure and covers all major implementation details.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/new-quote-errors-1

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.


// Conforms to backend API
// https://github.com/cowprotocol/services/blob/main/crates/orderbook/openapi.yml
// TODO: import from SDK `PriceEstimationError.errorType`

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 4, 2026

Copy link
Copy Markdown

Deploying explorer-dev with  Cloudflare Pages  Cloudflare Pages

Latest commit: da5625a
Status: ✅  Deploy successful!
Preview URL: https://e0d7c32a.explorer-dev-dxz.pages.dev
Branch Preview URL: https://feat-new-quote-errors-1.explorer-dev-dxz.pages.dev

View logs

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 4, 2026

Copy link
Copy Markdown

Deploying swap-dev with  Cloudflare Pages  Cloudflare Pages

Latest commit: da5625a
Status: ✅  Deploy successful!
Preview URL: https://5e87c473.swap-dev-5u6.pages.dev
Branch Preview URL: https://feat-new-quote-errors-1.swap-dev-5u6.pages.dev

View logs

@fairlighteth

Copy link
Copy Markdown
Contributor
AI Review (Codex GPT-5, worked 1m): follow-up acknowledged

Rechecked

  • Author response: @shoom3301 fixed NoLiquidity in SENTRY_IGNORED_QUOTE_ERRORS and intentionally left useTokenCustomTradeError() unchanged for now.
  • Code path: apps/cowswap-frontend/src/api/cowProtocol/errors/QuoteError.ts:33 and apps/cowswap-frontend/src/modules/tradeFormValidation/hooks/useTokenCustomTradeError.ts:24

Result: The Sentry finding is fixed. The weekend/RWA override still only handles InsufficientLiquidity, but based on the author’s reply I’m treating that as an intentional deferment rather than reopening it as a blocking review issue in this PR.

@fairlighteth fairlighteth self-requested a review June 8, 2026 09:27

@kernelwhisperer kernelwhisperer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just 1 minor issue regarding UNHANDLED_ERROR_CODE usage

Comment thread apps/cowswap-frontend/src/api/cowProtocol/getIsOrderBookTypedError.ts Outdated
Base automatically changed from feat/new-quote-errors to develop June 15, 2026 11:35
… feat/new-quote-errors-1

# Conflicts:
#	apps/cowswap-frontend/src/api/cowProtocol/errors/QuoteError.ts
#	apps/cowswap-frontend/src/locales/en-US.po
#	apps/cowswap-frontend/src/modules/tradeFormValidation/pure/QuoteApiErrorButton.pure.tsx
#	apps/cowswap-frontend/src/modules/tradeFormValidation/pure/QuoteErrorsButton/QuoteErrorsButton.pure.tsx
#	apps/cowswap-frontend/src/modules/tradeFormValidation/pure/QuoteErrorsButton/quoteErrors.utils.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
apps/cowswap-frontend/src/api/cowProtocol/errors/QuoteError.ts (1)

42-45: ⚡ Quick win

Export the unhandled-error sentinel to avoid string-literal drift across modules.

apps/cowswap-frontend/src/modules/tradeFormValidation/pure/QuoteApiErrorButton.pure.tsx currently checks 'UNHANDLED_ERROR' as a raw literal. Keeping this sentinel private here makes that cross-file contract brittle. Export the constant(s) and reuse them in UI branches.

Suggested patch
-const UNHANDLED_ERROR_CODE = 'UNHANDLED_ERROR' as const
+export const UNHANDLED_ERROR_CODE = 'UNHANDLED_ERROR' as const

-const UNHANDLED_ERROR_DESC =
+export const UNHANDLED_ERROR_DESC =
   'Quote fetch failed. This may be due to a server or network connectivity issue. Please try again later.'
🤖 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 `@apps/cowswap-frontend/src/api/cowProtocol/errors/QuoteError.ts` around lines
42 - 45, Export the UNHANDLED_ERROR_CODE constant from QuoteError.ts so it can
be reused across modules. Update the import in QuoteApiErrorButton.pure.tsx to
import UNHANDLED_ERROR_CODE from QuoteError.ts and use it in the conditional
check instead of the hardcoded string literal 'UNHANDLED_ERROR'. This ensures
the sentinel value is defined in a single place and referenced consistently,
eliminating string-literal drift between files.
🤖 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 `@apps/cowswap-frontend/src/api/cowProtocol/errors/QuoteError.ts`:
- Around line 42-45: Export the UNHANDLED_ERROR_CODE constant from QuoteError.ts
so it can be reused across modules. Update the import in
QuoteApiErrorButton.pure.tsx to import UNHANDLED_ERROR_CODE from QuoteError.ts
and use it in the conditional check instead of the hardcoded string literal
'UNHANDLED_ERROR'. This ensures the sentinel value is defined in a single place
and referenced consistently, eliminating string-literal drift between files.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c51837e1-e381-42fc-954f-8b71bcec5d24

📥 Commits

Reviewing files that changed from the base of the PR and between 8dd94a1 and dc6ffbb.

📒 Files selected for processing (9)
  • apps/cowswap-frontend/src/api/cowProtocol/errors/QuoteError.ts
  • apps/cowswap-frontend/src/api/cowProtocol/getIsOrderBookTypedError.ts
  • apps/cowswap-frontend/src/locales/en-US.po
  • apps/cowswap-frontend/src/modules/swap/containers/SwapWidget/index.tsx
  • apps/cowswap-frontend/src/modules/tradeFormValidation/hooks/useTokenCustomTradeError.ts
  • apps/cowswap-frontend/src/modules/tradeFormValidation/pure/QuoteApiErrorButton.pure.tsx
  • apps/cowswap-frontend/src/modules/tradeFormValidation/pure/QuoteErrorsButton/quoteErrors.utils.ts
  • apps/cowswap-frontend/src/modules/tradeQuote/services/fetchAndProcessQuote.test.ts
  • apps/cowswap-frontend/src/modules/tradeQuote/services/fetchAndProcessQuote.ts

@shoom3301 shoom3301 requested a review from a team June 15, 2026 11:47
@shoom3301 shoom3301 merged commit 0e533ad into develop Jun 15, 2026
18 of 19 checks passed
@shoom3301 shoom3301 deleted the feat/new-quote-errors-1 branch June 15, 2026 11:57
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 15, 2026
@elena-zh

Copy link
Copy Markdown
Contributor

Since the PR is merged, opened #7644 with related questions

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants