Skip to content

fix(desktop): surface invite creation errors separately from clipboard failures - #5037

Open
iroiro147 wants to merge 1 commit into
block:mainfrom
iroiro147:fix/3691-rebase
Open

fix(desktop): surface invite creation errors separately from clipboard failures#5037
iroiro147 wants to merge 1 commit into
block:mainfrom
iroiro147:fix/3691-rebase

Conversation

@iroiro147

Copy link
Copy Markdown
Contributor

Problem

When creating an invite link failed (e.g. CORS preflight rejected, 403 Forbidden, network timeout), the user saw "Couldn't copy the invite link. Try again." — misattributing a server/network error to the clipboard. This was actively misleading: the clipboard worked fine elsewhere in the app, but the error message sent users looking at Tauri clipboard permissions instead of the network.

Closes #3636 (desktop part)

Root Cause

handleCopy in InviteLinkSection.tsx wrapped both mintInvite and writeTextToClipboard in a single try/catch. Any failure from either call produced the same generic "couldn't copy" toast, discarding the actual error message from the relay.

invitePost already throws a useful Error — either the server's json.error string or HTTP <status> — but that message was being swallowed.

Solution

Split the single try/catch into two:

Failure Old message New message
mintInvite fails "Couldn't copy the invite link. Try again." "Couldn't create the invite: <error.message>"
writeTextToClipboard fails (same) "Invite created, but copying to the clipboard failed."

The second message is materially different: because relay_invites stores only token_hash, an invite whose code fails to reach the clipboard is unrecoverable. Telling the user it was created but not copied is different from telling them to just try again.

Test Plan

cd desktop
node --test src/features/community-members/ui/inviteLinkErrorSeparation.test.mjs

All 6 tests pass:

  • both succeed: copies invite and shows success toast
  • mintInvite fails: shows creation error, does not attempt clipboard
  • clipboard fails: shows clipboard-specific error, invite was created
  • mintInvite error message is surfaced to the user
  • non-Error thrown by mintInvite produces generic message
  • copying status is set during operation

Full desktop suite: pnpm test → 4393/4393 pass (includes the new file). pnpm typecheck clean.


Supersedes #3691 — identical change, rebased onto current main (96ae1417) to resolve the merge conflict in InviteLinkSection.tsx (upstream added a generated-invite cache/path that landed in the same hunk). No behavior change versus the original PR; conflict resolution kept this PR's two-try/catch structure and the upstream invite-request cache.

…d failures

The invite link copy handler wrapped both mintInvite and
writeTextToClipboard in a single try/catch. When mintInvite failed
(e.g. CORS preflight rejected, 403 Forbidden), the user saw
"Couldn't copy the invite link" — misattributing a server/network
error to the clipboard.

This separates the two failure modes:
- mintInvite failure: "Couldn't create the invite: <error message>"
  The error from invitePost (which includes the relay's json.error
  or HTTP status) is now surfaced to the user.
- clipboard failure: "Invite created, but copying to the clipboard
  failed." — distinct message acknowledging the invite was minted
  but copying failed (important because relay_invites stores only
  token_hash, so the code is unrecoverable).

Closes block#3636

Signed-off-by: iroiro147 <sarthak.singh@juspay.in>
@iroiro147
iroiro147 requested a review from a team as a code owner August 6, 2026 10:40
alex-erygin added a commit to alex-erygin/sharik that referenced this pull request Aug 6, 2026
@ravarora2

Copy link
Copy Markdown
Contributor

🤖 Reviewed on behalf of @ravarora2.

Thanks for chasing this down — the underlying report (#3636) is real, but I think this fix is aimed at a version of the code that no longer exists on main, and applying it would regress the current invite flow. Wanted to lay out the details.

The desktop half of #3636 is already fixed on main

#4734 "Refine community invite links" (which is already in this PR's base) moved minting out of handleCopy into an eager generateInviteLink() effect that runs when the section opens / settings change. That effect has its own error path, so the two failure modes are already separated:

  • mint failure → toast.error("Couldn’t create an invite link.") + a failed state + a Retry button + the "Couldn’t create invite link" placeholder.
  • clipboard failure → handleCopy's catch, which now only ever wraps writeTextToClipboard(inviteUrl), so it genuinely is a clipboard error.

So the misattribution the PR targets (mint error shown as "Couldn't copy…") can't happen on current main anymore.

Re-adding mintInvite into handleCopy regresses the flow

This diff re-inserts mintInvite({ ttlSecs, maxUses }) into handleCopy on top of the eager mint. Concretely that causes:

  1. Double-minting. generateInviteLink already minted the invite that fills inviteUrl when the dialog opened. With this change, every click of "Copy link" mints another durable invite on the relay (relay_invites row per click). The eagerly-minted one becomes an orphaned, still-claimable code.
  2. Copy ≠ what's shown. The input displays inviteUrl (first mint); handleCopy now copies invite.url from the second mint — a different code.
  3. Clipboard-gesture risk. Putting a network round-trip (mintInvite, up to the 15s timeout) before writeTextToClipboard can drop the user-activation gesture and make the clipboard write itself fail — arguably the class of failure the eager-mint design was avoiding.

The test doesn't exercise the component

inviteLinkErrorSeparation.test.mjs re-implements a fake handleCopy state machine inside the test and asserts against that copy — it never imports InviteLinkSection. So the 6 tests stay green regardless of the double-mint behavior in the real component.

Suggestion

I'd lean toward closing this in favor of #4734, since the desktop symptom is resolved there. If there's still a wording nit worth keeping (e.g. the copy-failure toast could hint the link is still visible / regenerable), that's a one-line change in the existing handleCopy catch — no new mintInvite call and no structural change. If a test is desired, it'd be great to exercise the real handleCopy rather than a hand-rewritten copy.

Happy to help re-scope if you'd like to keep a slimmed-down version.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A rejected CORS preflight is invisible on both sides: no relay log at any level, and the desktop reports it as a clipboard failure

2 participants