refactor(desktop): share mention send error presentation

Extract the identical authorization-aware error presentation from both send failure paths so normal formatter output respects the file-size ratchet.

Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Signed-off-by: Logan Johnson <loganj@squareup.com>
This commit is contained in:
Logan Johnson
2026-09-08 13:57:20 -04:00
parent 85ac1bc6a2
commit 30bc57da82
3 changed files with 34 additions and 13 deletions

View File

@@ -3,11 +3,31 @@ import test from "node:test";
import {
formatMessageSendError,
formatMentionSendError,
getErrorMessage,
mergeMentionRecipients,
mentionRevalidationOptions,
} from "./useMentionSendFlow.helpers.ts";
import { AgentMentionAuthorizationError } from "../lib/agentMentionRevalidation.ts";
test("mention send errors preserve authorization guidance and generic failure details", () => {
const denied = new AgentMentionAuthorizationError();
assert.equal(formatMentionSendError(denied), denied.message);
assert.equal(
formatMentionSendError(new Error("relay rejected")),
"Message failed to send: relay rejected",
);
assert.equal(
formatMentionSendError("upload rejected"),
"Message failed to send: upload rejected",
);
assert.equal(
formatMentionSendError({}),
"Message failed to send: Unknown error",
);
});
test("formatMessageSendError preserves the publication failure", () => {
assert.equal(
formatMessageSendError(new Error("relay rejected voice note")),

View File

@@ -1,4 +1,7 @@
import type { MentionRevalidationOptions } from "@/features/messages/lib/agentMentionRevalidation";
import {
AgentMentionAuthorizationError,
type MentionRevalidationOptions,
} from "@/features/messages/lib/agentMentionRevalidation";
import type { ManagedAgent } from "@/shared/api/types";
import {
type ImetaMedia,
@@ -110,6 +113,13 @@ export function formatMessageSendError(error: unknown) {
return `Message failed to send: ${getErrorMessage(error, "Unknown error")}`;
}
/** Preserve actionable authorization errors without the generic send-failure prefix. */
export function formatMentionSendError(error: unknown) {
return error instanceof AgentMentionAuthorizationError
? error.message
: formatMessageSendError(error);
}
export function uniqueNormalizedPubkeys(pubkeys: Iterable<string>) {
return [...new Set([...pubkeys].map(normalizePubkey))].filter(Boolean);
}

View File

@@ -31,7 +31,7 @@ import type { ManagedAgent } from "@/shared/api/types";
import { normalizePubkey, truncatePubkey } from "@/shared/lib/pubkey";
import { buildCustomEmojiTags } from "@/shared/lib/customEmojiTags";
import {
formatMessageSendError,
formatMentionSendError,
getErrorMessage,
mentionRevalidationOptions,
withoutInvitingRecipients,
@@ -44,7 +44,6 @@ import {
uniqueNormalizedPubkeys,
} from "./useMentionSendFlow.helpers";
import { buildAgentAddressMentionTags } from "@/features/messages/lib/agentAddressMention.mjs";
import { AgentMentionAuthorizationError } from "@/features/messages/lib/agentMentionRevalidation";
import type { UseMentionSendFlowOptions } from "./useMentionSendFlow.types";
export function useMentionSendFlow({
@@ -650,11 +649,7 @@ export function useMentionSendFlow({
await finishSend(uploaded, signal);
} catch (error) {
restoreComposerAfterFailure();
toast.error(
error instanceof AgentMentionAuthorizationError
? error.message
: formatMessageSendError(error),
);
toast.error(formatMentionSendError(error));
} finally {
settleUpload();
}
@@ -682,11 +677,7 @@ export function useMentionSendFlow({
await finishSend([]);
} catch (error) {
restoreComposerAfterFailure();
toast.error(
error instanceof AgentMentionAuthorizationError
? error.message
: formatMessageSendError(error),
);
toast.error(formatMentionSendError(error));
}
}
} catch (error) {