fix(web): friend-add error toasts surface raw codes — read err.message, not err.body
The T19/T20 catch blocks looked for an `.body` property on thrown errors to extract the structured error code. The shared API client (api/client.ts:298) actually throws `new Error(body.error)` — the code lives in `err.message`, and there's no `.body` attached. Live E2E (T22 scenario 2) caught this: typing alice@orbit against an awaiting_approval peer surfaced the raw code 'peer_pending_approval' as the toast text instead of the human-readable mapServerErrorToMessage output. Same defect would have hit every server-error toast on both FriendsPage (AddFriend + UserDiscoverCard) and UserProfileModal. Catch blocks now use err.message as both the code and the fallback text; the inline comment points at the API client throw site so the contract is documented at the consumer.
This commit is contained in:
@@ -476,16 +476,12 @@ function AddFriendTab({
|
||||
addToast('Friend request sent!', 'success');
|
||||
setQuery('');
|
||||
} catch (err) {
|
||||
const errorBody = (err as { body?: unknown })?.body;
|
||||
let code: string | undefined;
|
||||
let message: string | undefined;
|
||||
if (errorBody && typeof errorBody === 'object') {
|
||||
code = (errorBody as { error?: string }).error;
|
||||
message = (errorBody as { message?: string }).message;
|
||||
}
|
||||
// Fall back to the Error message if the server didn't send a structured body.
|
||||
const fallback = message ?? (err instanceof Error ? err.message : undefined);
|
||||
addToast(mapServerErrorToMessage(code, fallback, query.trim()), 'warning');
|
||||
// The shared API client throws `new Error(body.error)` for non-2xx
|
||||
// responses (api/client.ts:298), so `err.message` carries the server's
|
||||
// error code (e.g. 'peer_pending_approval'). It also doubles as fallback
|
||||
// text if the code is unrecognized by mapServerErrorToMessage.
|
||||
const code = err instanceof Error ? err.message : undefined;
|
||||
addToast(mapServerErrorToMessage(code, code, query.trim()), 'warning');
|
||||
} finally {
|
||||
setDirectAddLoading(false);
|
||||
}
|
||||
@@ -643,15 +639,9 @@ function UserDiscoverCard({
|
||||
const requestId = await sendFriendRequest(username);
|
||||
onRelationshipChange(user.id, user._instanceOrigin, 'outbound_pending', requestId);
|
||||
} catch (err) {
|
||||
const errorBody = (err as { body?: unknown })?.body;
|
||||
let code: string | undefined;
|
||||
let message: string | undefined;
|
||||
if (errorBody && typeof errorBody === 'object') {
|
||||
code = (errorBody as { error?: string }).error;
|
||||
message = (errorBody as { message?: string }).message;
|
||||
}
|
||||
const fallback = message ?? (err instanceof Error ? err.message : 'Failed to send request');
|
||||
setError(mapServerErrorToMessage(code, fallback, username));
|
||||
// See handleDirectAdd above — err.message is the server error code.
|
||||
const code = err instanceof Error ? err.message : undefined;
|
||||
setError(mapServerErrorToMessage(code, code ?? 'Failed to send request', username));
|
||||
} finally {
|
||||
setActionLoading(false);
|
||||
}
|
||||
|
||||
@@ -186,15 +186,11 @@ export function UserProfileModal() {
|
||||
try {
|
||||
await sendFriendRequest(user.username);
|
||||
} catch (err) {
|
||||
const errorBody = (err as { body?: unknown })?.body;
|
||||
let code: string | undefined;
|
||||
let message: string | undefined;
|
||||
if (errorBody && typeof errorBody === 'object') {
|
||||
code = (errorBody as { error?: string }).error;
|
||||
message = (errorBody as { message?: string }).message;
|
||||
}
|
||||
const fallback = message ?? (err instanceof Error ? err.message : undefined);
|
||||
addToast(mapServerErrorToMessage(code, fallback, user.username), 'warning');
|
||||
// The shared API client throws `new Error(body.error)` for non-2xx
|
||||
// responses (api/client.ts:298), so err.message carries the server's
|
||||
// error code (e.g. 'peer_pending_approval').
|
||||
const code = err instanceof Error ? err.message : undefined;
|
||||
addToast(mapServerErrorToMessage(code, code, user.username), 'warning');
|
||||
} finally {
|
||||
setFriendActionLoading(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user