fix(components): show server-supplied error messages on the sign-in form - #2396
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The Storybook title change likely breaks existing Cypress navigation by story ID, and completeActivation() still doesn’t clear verificationCode on network/exception failures despite the stated behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Updates the components sign-in/activation flow to prefer user-facing error messages returned by the activation API on 4xx responses, and adjusts UX so the email address is not cleared on error. Adds unit/e2e coverage and Storybook stories to exercise the new denial-message paths without requiring a live server.
Changes:
- Prefer server-supplied
error.messagefor 4xx responses in activation + verification flows (fallback to existing client messages otherwise). - Keep the email input value on failure (while still clearing verification code where applicable).
- Add unit tests, Cypress e2e coverage, and Storybook stories for the denial-message scenarios via stubbed fetch.
File summaries
| File | Description |
|---|---|
| packages/components/tests/unit/SignIn.spec.js | Adds unit coverage for server-supplied error messages + email retention on errors. |
| packages/components/tests/e2e/specs/sidebarSignIn.spec.js | Adds Cypress coverage for displaying server-supplied denial messages in both activation and verification. |
| packages/components/src/stories/SignIn.stories.js | Adds Storybook stories that stub fetch to simulate denied activation/verification responses. |
| packages/components/src/components/SignIn.vue | Implements serverMessage() and updates error handling to prefer server messages on 4xx while keeping email input on failure. |
Review details
Suppressed comments (1)
packages/components/src/components/SignIn.vue:277
completeActivation()clearsverificationCodefor HTTP error responses, but on outright request failures (thecatchbranch) it leaves the verification code intact. The PR description says the verification code still clears on error; this currently doesn’t happen for network/exception failures.
this.error = GENERIC_ERROR_MSG;
}
} catch (error) {
this.error = GENERIC_ERROR_MSG;
this.submitted = false;
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The activation endpoints can answer a 4xx with a body of the form
{"error": {"code": ..., "message": ...}}, explaining in the user's terms
why the request was rejected. The form discarded it and always displayed
its own guess -- "Invalid email address, please try again." -- which is
misleading whenever the request failed for any reason other than a
malformed field, and leaves the user with no idea what to do next.
Prefer the server's message when a 4xx carries one. The error code is
deliberately ignored: the message is the part written for the user, and
matching on codes would leave every code the server adds later falling
back to the misleading wording. Every other shape keeps the existing
text -- a non-JSON body, a missing, blank or non-string message, and any
5xx, whose body is an internal error or a proxy's HTML rather than
anything worth showing.
Also stop clearing the email input on error. Making the user retype an
address after a network blip serves no purpose, and blanking the field
hides the very address the message is about. The verification code still
clears, and "try again" still resets both.
The two new Storybook stories drive these paths through a stubbed fetch,
so the error handling can be exercised without a server.
Assisted-by: Claude:claude-opus-5[1m]
b70c862 to
cd897e6
Compare
The activation endpoints can answer a 4xx with a body of the form {"error": {"code": ..., "message": ...}}, explaining in the user's terms why the request was rejected. The form discarded it and always displayed its own guess -- "Invalid email address, please try again." -- which is misleading whenever the request failed for any reason other than a malformed field, and leaves the user with no idea what to do next.
Prefer the server's message when a 4xx carries one. The error code is deliberately ignored: the message is the part written for the user, and matching on codes would leave every code the server adds later falling back to the misleading wording. Every other shape keeps the existing text -- a non-JSON body, a missing, blank or non-string message, and any 5xx, whose body is an internal error or a proxy's HTML rather than anything worth showing.
Also stop clearing the email input on error. Making the user retype an address after a network blip serves no purpose, and blanking the field hides the very address the message is about. The verification code still clears, and "try again" still resets both.
The two new Storybook stories drive these paths through a stubbed fetch, so the error handling can be exercised without a server.
Assisted-by: Claude:claude-opus-5[1m]