Repository navigation
feat(marketplace): explain SellerNotRegistered with a 400 and reason seller_not_registered - #1559
Conversation
…seller_not_registered An RI Marketplace listing from an account that is not a registered seller came back as a 400 carrying AWS's own SellerNotRegistered text, which does not say how to fix it. mapAWSMarketplaceError now answers that code with a fixed message (the account's root user must register it as a seller with a bank account that has a US address, linking the AWS guide) and a stable details.reason "seller_not_registered", flattened into the JSON body as "reason" so clients can branch without matching text. It keys on the code alone, whatever fault AWS reports. The status stays 400, so the attempt token is still dropped as for any client fault. Other client faults keep AWS's message and carry no reason. openapi.yaml documents the reason on the marketplace-list and marketplace-cancel 400s (both go through the same mapping) via a new MarketplaceClientError schema. Refs LeanerCloud#27 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 58 minutes. View limit details
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. Comment |
govulncheck in the Docker image build now fails on these two advisories, both fixed in x/net v0.62.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): VERDICT: APPROVE Blocking:
Non-blocking:
Attacked:
Body-stale:
Reviewer: rG1. Bar while the maintainers are away (set by IAmJSD as acting owner): one approving independent review on the head, two for money, auth and security paths. |
|
Local verification at |
|
Merged by IAmJSD's agent at IAmJSD's request (IAmJSD is acting owner while the maintainers are away), under the bar IAmJSD set: 1 approving independent review(s) on |
Root cause
Before this PR,
mapAWSMarketplaceErrorhandled AWS'sSellerNotRegisteredthe same way as every other client-fault code: a 400 carrying AWS's own message. That text only says the account isn't a registered seller. It doesn't tell the user how to fix it, and there was nothing a client could branch on to show its own guidance.Fix
mapAWSMarketplaceError(internal/api/handler_marketplace.go) now handlesSellerNotRegisteredbefore the generic client-fault check. It returns a 400 with:errormessage: the account's root user must register it as a Reserved Instance Marketplace seller, with a bank account that has a US address, before it can list. The message links the AWS guide at https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-market-general.html#ri-market-seller-profile.details.reason = "seller_not_registered". The response writer flattens it into the JSON body:{"error": "...", "reason": "seller_not_registered"}.Behavior notes:
isClientFaultErrortherefore still drops the attempt's client token, exactly as before.reason.SellerNotRegisteredfromawsMarketplaceClientFaultCodes, because the new branch makes that entry unreachable. A comment on the set says so.internal/api/openapi.yamlgets a newMarketplaceClientErrorschema (error, plus an optionalreasonwith enum[seller_not_registered]). It's used on the 400 for bothmarketplace-listandmarketplace-cancel, since both go through the same mapping, and the 400 descriptions now explain the reason.There's no DB change and no migration. The change only maps an error that has already happened, so concurrency doesn't come into it.
Refs #27
Verification
Unit and mock evidence only. No real AWS calls were made.
Fail-before: the message constant was in place but the new branch wasn't.
Pass-after:
What the tests cover:
TestMarketplaceListHTTP_SellerNotRegisteredExplainsRegistrationdrivesPOST /marketplace-listthroughHandleRequestagainst the fake listing DB. It asserts:errorplusreason, nothing else);TestMapAWSMarketplaceError_SellerNotRegisteredwraps the code in an EC2smithy.OperationErrorwith both a client fault and an unknown fault. It asserts:Details()is exactly{reason: seller_not_registered}.TestMapAWSMarketplaceError_OtherClientFaultsHaveNoReasonpins thatInvalidParameterValuekeeps its AWS message and has nil details. It's a guard against a broader mutation, so it passes both before and after.Other checks:
Combined-tree verification. This branch was tested together with the other queued branches on a local, never-pushed tree:
queue/platform@400d256b= origin/main7b86e386plus these heads, merged in this order:Linux, Go 1.26.9,
AWS_CONFIG_FILE=/dev/null AWS_SHARED_CREDENTIALS_FILE=/dev/null AWS_EC2_METADATA_DISABLED=true; Docker Postgres via testcontainers. The full suite ran onf7c48020, which differs from this tree only by test-only commits on fix/issue-30, fix/issue-713 and fix/issue-263 that replace placeholder account-number literals with named constants:go build ./...,go vet ./...,go vet -tags integration ./...and the fullgo test -race -short -count=1 ./....--build-tags integration.gocyclo -over 10is silent on the changed non-test files.-tags integration -count=1):internal/analytics,internal/api,internal/auth,internal/config,internal/database/postgres/migrations,internal/purchase,internal/schedulerandinternal/serverall pass. Migrations 000149, 000150 and 000151 apply in order on this tree.approval-details,settings-accounts,api) pass (221 tests).accountkey); fixed with named constants. Re-run on this tree: git-secrets, using the repo'sscripts/setup-git-secrets.shpatterns in a fresh repo with an isolated HOME, found nothing in the changed files, and a planted fake key was flagged.scripts/test-git-secrets-allowlist.sh: 183 PASS, 0 FAIL..tftest.hclfiles were not run locally (CI runs them). Nothing was applied to any cloud.Out of scope
Refs.Frontend follow-up for the UI owner
The current UI already shows the new
errortext throughapiRequest's message handling, so users see the guidance without any frontend change. The URL appears as plain text, though.apiRequestputs the rest of the JSON body onerror.details, so the Sell flow (frontend/src/history.ts, aroundapi.createMarketplaceListing) could branch onerror.details.reason === 'seller_not_registered'to:Maintainer: please mirror the issue's triage labels onto this PR:
effort/l,impact/few,priority/p2,severity/low,triaged,type/feat,urgency/eventually.🤖 Generated with Claude Code