From 5fb4b66194ca1711df794489b46eb7102b022382 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Wed, 27 May 2026 09:03:37 +0530 Subject: [PATCH 1/2] fix(admin): surface API error message in toasts Forward ConnectError.rawMessage into the toast description for the remaining admin catch blocks that previously showed only a generic error: project member removal, project rename, preference save, and webhook create/update/delete. Falls back to no description for non-ConnectError errors so behavior is unchanged for those. --- .../details/projects/members/remove-member.tsx | 7 ++++++- .../organizations/details/projects/rename-project.tsx | 7 ++++++- web/sdk/admin/views/preferences/details.tsx | 7 ++++++- web/sdk/admin/views/webhooks/webhooks/create/index.tsx | 7 ++++++- web/sdk/admin/views/webhooks/webhooks/delete/index.tsx | 7 ++++++- web/sdk/admin/views/webhooks/webhooks/update/index.tsx | 7 ++++++- 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/web/sdk/admin/views/organizations/details/projects/members/remove-member.tsx b/web/sdk/admin/views/organizations/details/projects/members/remove-member.tsx index 6317795f8..c768723bd 100644 --- a/web/sdk/admin/views/organizations/details/projects/members/remove-member.tsx +++ b/web/sdk/admin/views/organizations/details/projects/members/remove-member.tsx @@ -5,6 +5,7 @@ import { type SearchProjectUsersResponse_ProjectUser, } from "@raystack/proton/frontier"; import { create } from "@bufbuild/protobuf"; +import { ConnectError } from "@connectrpc/connect"; import { useMutation } from "@connectrpc/connect-query"; import styles from "./members.module.css"; @@ -49,7 +50,11 @@ export const RemoveMember = ({ toastManager.add({ title: `${t.member({ case: "capital" })} removed successfully`, type: "success" }); } catch (error) { - toastManager.add({ title: `Failed to remove ${t.member({ case: "lower" })}`, type: "error" }); + toastManager.add({ + title: `Failed to remove ${t.member({ case: "lower" })}`, + description: error instanceof ConnectError ? error.rawMessage : undefined, + type: "error", + }); console.error(error); } finally { setIsSubmitting(false); diff --git a/web/sdk/admin/views/organizations/details/projects/rename-project.tsx b/web/sdk/admin/views/organizations/details/projects/rename-project.tsx index 74adb4381..b7577fcfe 100644 --- a/web/sdk/admin/views/organizations/details/projects/rename-project.tsx +++ b/web/sdk/admin/views/organizations/details/projects/rename-project.tsx @@ -9,6 +9,7 @@ import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm, Controller } from "react-hook-form"; import React from "react"; +import { ConnectError } from "@connectrpc/connect"; import { useMutation } from "@connectrpc/connect-query"; import { useTerminology } from "../../../../hooks/useTerminology"; @@ -72,7 +73,11 @@ export function RenameProjectDialog({ }); } } catch (error) { - toastManager.add({ title: `Failed to rename ${t.project({ case: "lower" })}`, type: "error" }); + toastManager.add({ + title: `Failed to rename ${t.project({ case: "lower" })}`, + description: error instanceof ConnectError ? error.rawMessage : undefined, + type: "error", + }); console.error(error); } }; diff --git a/web/sdk/admin/views/preferences/details.tsx b/web/sdk/admin/views/preferences/details.tsx index d6240b0ee..d60943a30 100644 --- a/web/sdk/admin/views/preferences/details.tsx +++ b/web/sdk/admin/views/preferences/details.tsx @@ -12,6 +12,7 @@ import { import { useCallback, useEffect, useState } from "react"; import Skeleton from "react-loading-skeleton"; import dayjs from "dayjs"; +import { ConnectError } from "@connectrpc/connect"; import { useMutation, createConnectQueryKey, useTransport } from "@connectrpc/connect-query"; import { AdminServiceQueries, CreatePreferencesRequestSchema, ListPreferencesResponse } from "@raystack/proton/frontier"; import { Preference, PreferenceTrait, PreferenceTrait_InputType } from "@raystack/proton/frontier"; @@ -186,7 +187,11 @@ export default function PreferenceDetails({ toastManager.add({ title: "preference updated", type: "success" }); } catch (err) { console.error("ConnectRPC Error:", err); - toastManager.add({ title: "something went wrong", type: "error" }); + toastManager.add({ + title: "something went wrong", + description: err instanceof ConnectError ? err.rawMessage : undefined, + type: "error", + }); } }, [name, value, createPreferences]); diff --git a/web/sdk/admin/views/webhooks/webhooks/create/index.tsx b/web/sdk/admin/views/webhooks/webhooks/create/index.tsx index da55b35eb..5421f7f17 100644 --- a/web/sdk/admin/views/webhooks/webhooks/create/index.tsx +++ b/web/sdk/admin/views/webhooks/webhooks/create/index.tsx @@ -8,6 +8,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { Form, FormSubmit } from "@radix-ui/react-form"; import { CustomFieldName } from "../../../../components/CustomField"; import events from "../../../../utils/webhook-events"; +import { ConnectError } from "@connectrpc/connect"; import { useMutation } from "@connectrpc/connect-query"; import { AdminServiceQueries, @@ -69,7 +70,11 @@ export default function CreateWebhooks({ open = false, onClose: onCloseProp }: C } } catch (err) { console.error("Failed to create webhook:", err); - toastManager.add({ title: "Something went wrong", type: "error" }); + toastManager.add({ + title: "Something went wrong", + description: err instanceof ConnectError ? err.rawMessage : undefined, + type: "error", + }); } }; diff --git a/web/sdk/admin/views/webhooks/webhooks/delete/index.tsx b/web/sdk/admin/views/webhooks/webhooks/delete/index.tsx index 85b6e66be..6dd3fb21c 100644 --- a/web/sdk/admin/views/webhooks/webhooks/delete/index.tsx +++ b/web/sdk/admin/views/webhooks/webhooks/delete/index.tsx @@ -1,4 +1,5 @@ import { Button, Dialog, Flex, Text, toastManager } from "@raystack/apsara-v1"; +import { ConnectError } from "@connectrpc/connect"; import type { useMutation } from "@connectrpc/connect-query"; interface DeleteWebhookDialogProps { @@ -23,7 +24,11 @@ export function DeleteWebhookDialog({ onOpenChange(false); } catch (err) { console.error("Failed to delete webhook:", err); - toastManager.add({ title: "Failed to delete webhook", type: "error" }); + toastManager.add({ + title: "Failed to delete webhook", + description: err instanceof ConnectError ? err.rawMessage : undefined, + type: "error", + }); } }; diff --git a/web/sdk/admin/views/webhooks/webhooks/update/index.tsx b/web/sdk/admin/views/webhooks/webhooks/update/index.tsx index 97b49a749..24eaba814 100644 --- a/web/sdk/admin/views/webhooks/webhooks/update/index.tsx +++ b/web/sdk/admin/views/webhooks/webhooks/update/index.tsx @@ -8,6 +8,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { Form, FormSubmit } from "@radix-ui/react-form"; import { CustomFieldName } from "../../../../components/CustomField"; import events from "../../../../utils/webhook-events"; +import { ConnectError } from "@connectrpc/connect"; import { useMutation } from "@connectrpc/connect-query"; import { AdminServiceQueries, @@ -85,7 +86,11 @@ export default function UpdateWebhooks({ open = false, webhookId: webhookIdProp, } } catch (err) { console.error("Failed to update webhook:", err); - toastManager.add({ title: "Something went wrong", type: "error" }); + toastManager.add({ + title: "Something went wrong", + description: err instanceof ConnectError ? err.rawMessage : undefined, + type: "error", + }); } }; From dad9df041f56841e979f6a05dec7cf241dc7a09b Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Wed, 27 May 2026 14:53:44 +0530 Subject: [PATCH 2/2] fix(admin): update error handling to use rawMessage in toast notifications Refactor error handling across various admin components to display the rawMessage from ConnectError in toast notifications instead of the generic error message. This change enhances the clarity of error reporting for users. --- .../admin/views/organizations/details/edit/billing.tsx | 2 +- web/sdk/admin/views/organizations/details/edit/kyc.tsx | 2 +- .../organizations/details/layout/add-tokens-dialog.tsx | 2 +- .../details/layout/invite-users-dialog.tsx | 4 ++-- .../organizations/details/members/remove-member.tsx | 10 +++++----- .../details/projects/use-add-project-members.tsx | 4 ++-- .../details/security/block-organization.tsx | 4 ++-- .../organizations/details/security/domains-list.tsx | 2 +- .../admin/views/users/details/security/block-user.tsx | 4 ++-- .../security/sessions/revoke-session-final-confirm.tsx | 5 ++++- web/sdk/admin/views/users/list/invite-users.tsx | 4 ++-- 11 files changed, 23 insertions(+), 20 deletions(-) diff --git a/web/sdk/admin/views/organizations/details/edit/billing.tsx b/web/sdk/admin/views/organizations/details/edit/billing.tsx index fa477fa63..444af3223 100644 --- a/web/sdk/admin/views/organizations/details/edit/billing.tsx +++ b/web/sdk/admin/views/organizations/details/edit/billing.tsx @@ -117,7 +117,7 @@ export function EditBillingPanel({ open = false, onClose }: EditBillingPanelProp onError: (error) => { toastManager.add({ title: "Something went wrong", - description: error.message, + description: error.rawMessage, type: "error", }); console.error("Unable to update billing details:", error); diff --git a/web/sdk/admin/views/organizations/details/edit/kyc.tsx b/web/sdk/admin/views/organizations/details/edit/kyc.tsx index 144d3ec5f..d7c96ccaf 100644 --- a/web/sdk/admin/views/organizations/details/edit/kyc.tsx +++ b/web/sdk/admin/views/organizations/details/edit/kyc.tsx @@ -86,7 +86,7 @@ export function EditKYCPanel({ open = false, onClose }: EditKYCPanelProps) { onClose(); }, onError: (error) => { - toastManager.add({ title: `Failed to update KYC details: ${error.message}`, type: "error" }); + toastManager.add({ title: "Failed to update KYC details", description: error.rawMessage, type: "error" }); console.error("Unable to update KYC details:", error); }, }); diff --git a/web/sdk/admin/views/organizations/details/layout/add-tokens-dialog.tsx b/web/sdk/admin/views/organizations/details/layout/add-tokens-dialog.tsx index 0510a6e87..2c3ca7abd 100644 --- a/web/sdk/admin/views/organizations/details/layout/add-tokens-dialog.tsx +++ b/web/sdk/admin/views/organizations/details/layout/add-tokens-dialog.tsx @@ -71,7 +71,7 @@ export const AddTokensDialog = ({ onOpenChange }: InviteUsersDialogProps) => { onError: (error) => { toastManager.add({ title: "Something went wrong", - description: error.message, + description: error.rawMessage, type: "error", }); console.error("Unable to add tokens:", error); diff --git a/web/sdk/admin/views/organizations/details/layout/invite-users-dialog.tsx b/web/sdk/admin/views/organizations/details/layout/invite-users-dialog.tsx index f0508a7a2..f8f7594da 100644 --- a/web/sdk/admin/views/organizations/details/layout/invite-users-dialog.tsx +++ b/web/sdk/admin/views/organizations/details/layout/invite-users-dialog.tsx @@ -98,11 +98,11 @@ export const InviteUsersDialog = ({ onOpenChange }: InviteUsersDialogProps) => { handleConnectError(error, { AlreadyExists: () => toastManager.add({ title: 'Invitation already exists', type: "error" }), InvalidArgument: err => - toastManager.add({ title: 'Invalid input', description: err.message, type: "error" }), + toastManager.add({ title: 'Invalid input', description: err.rawMessage, type: "error" }), PermissionDenied: () => toastManager.add({ title: "You don't have permission to perform this action", type: "error" }), Default: err => - toastManager.add({ title: 'Something went wrong', description: err.message, type: "error" }) + toastManager.add({ title: 'Something went wrong', description: err.rawMessage, type: "error" }) }); } }; diff --git a/web/sdk/admin/views/organizations/details/members/remove-member.tsx b/web/sdk/admin/views/organizations/details/members/remove-member.tsx index 28f02f866..062d81d2f 100644 --- a/web/sdk/admin/views/organizations/details/members/remove-member.tsx +++ b/web/sdk/admin/views/organizations/details/members/remove-member.tsx @@ -42,11 +42,11 @@ export const RemoveMember = ({ } toastManager.add({ title: `${t.member({ case: "capital" })} removed successfully`, type: "success" }); } catch (error) { - const message = - error instanceof ConnectError - ? error.message - : "Unknown error"; - toastManager.add({ title: `Failed to remove ${t.member({ case: "lower" })}: ${message}`, type: "error" }); + toastManager.add({ + title: `Failed to remove ${t.member({ case: "lower" })}`, + description: error instanceof ConnectError ? error.rawMessage : undefined, + type: "error", + }); console.error(error); } } diff --git a/web/sdk/admin/views/organizations/details/projects/use-add-project-members.tsx b/web/sdk/admin/views/organizations/details/projects/use-add-project-members.tsx index 9c882c1ab..8602a60d8 100644 --- a/web/sdk/admin/views/organizations/details/projects/use-add-project-members.tsx +++ b/web/sdk/admin/views/organizations/details/projects/use-add-project-members.tsx @@ -85,8 +85,8 @@ export function useAddProjectMembers({ projectId }: useAddProjectMembersProps) { handleConnectError(error, { AlreadyExists: () => toastManager.add({ title: `${memberLabel} already exists in this project`, type: "error" }), PermissionDenied: () => toastManager.add({ title: "You don't have permission to perform this action", type: "error" }), - InvalidArgument: (err) => toastManager.add({ title: 'Invalid input', description: err.message, type: "error" }), - Default: (err) => toastManager.add({ title: 'Something went wrong', description: err.message, type: "error" }), + InvalidArgument: (err) => toastManager.add({ title: 'Invalid input', description: err.rawMessage, type: "error" }), + Default: (err) => toastManager.add({ title: 'Something went wrong', description: err.rawMessage, type: "error" }), }); } }, diff --git a/web/sdk/admin/views/organizations/details/security/block-organization.tsx b/web/sdk/admin/views/organizations/details/security/block-organization.tsx index 19a4dd2f9..8458499d1 100644 --- a/web/sdk/admin/views/organizations/details/security/block-organization.tsx +++ b/web/sdk/admin/views/organizations/details/security/block-organization.tsx @@ -45,7 +45,7 @@ const BlockOrganizationDialog = () => { onError: (error) => { toastManager.add({ title: "Something went wrong", - description: error.message, + description: error.rawMessage, type: "error", }); console.error("Failed to block organization:", error); @@ -71,7 +71,7 @@ const BlockOrganizationDialog = () => { onError: (error) => { toastManager.add({ title: "Something went wrong", - description: error.message, + description: error.rawMessage, type: "error", }); console.error("Failed to unblock organization:", error); diff --git a/web/sdk/admin/views/organizations/details/security/domains-list.tsx b/web/sdk/admin/views/organizations/details/security/domains-list.tsx index 13e964cd4..32eb0a0de 100644 --- a/web/sdk/admin/views/organizations/details/security/domains-list.tsx +++ b/web/sdk/admin/views/organizations/details/security/domains-list.tsx @@ -46,7 +46,7 @@ const DeleteDomainDialog = ({ onError: (error) => { toastManager.add({ title: "Something went wrong", - description: error.message, + description: error.rawMessage, type: "error", }); console.error("Unable to delete domain:", error); diff --git a/web/sdk/admin/views/users/details/security/block-user.tsx b/web/sdk/admin/views/users/details/security/block-user.tsx index e0f48c864..5e278416f 100644 --- a/web/sdk/admin/views/users/details/security/block-user.tsx +++ b/web/sdk/admin/views/users/details/security/block-user.tsx @@ -92,8 +92,8 @@ export const BlockUserDialog = () => { } catch (error) { handleConnectError(error, { PermissionDenied: () => toastManager.add({ title: "You don't have permission to perform this action", type: "error" }), - NotFound: (err) => toastManager.add({ title: 'Not found', description: err.message, type: "error" }), - Default: (err) => toastManager.add({ title: errorMessage, description: err.message, type: "error" }), + NotFound: (err) => toastManager.add({ title: 'Not found', description: err.rawMessage, type: "error" }), + Default: (err) => toastManager.add({ title: errorMessage, description: err.rawMessage, type: "error" }), }); } }; diff --git a/web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx b/web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx index 2c995ce06..ea5dc66b1 100644 --- a/web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx +++ b/web/sdk/admin/views/users/details/security/sessions/revoke-session-final-confirm.tsx @@ -5,6 +5,7 @@ import { Flex, Text } from '@raystack/apsara-v1'; +import { ConnectError } from '@connectrpc/connect'; import styles from './sessions.module.css'; interface RevokeSessionFinalConfirmProps { @@ -27,7 +28,9 @@ export const RevokeSessionFinalConfirm = ({ } catch (error: any) { toastManager.add({ title: 'Failed to revoke session', - description: error.message || 'Something went wrong', + description: + (error instanceof ConnectError ? error.rawMessage : error?.message) || + 'Something went wrong', type: "error", }); } diff --git a/web/sdk/admin/views/users/list/invite-users.tsx b/web/sdk/admin/views/users/list/invite-users.tsx index 9b998f108..ddde5e5ff 100644 --- a/web/sdk/admin/views/users/list/invite-users.tsx +++ b/web/sdk/admin/views/users/list/invite-users.tsx @@ -122,9 +122,9 @@ export const InviteUser = () => { } catch (error) { handleConnectError(error, { AlreadyExists: () => toastManager.add({ title: 'Invitation already exists', type: "error" }), - InvalidArgument: (err) => toastManager.add({ title: 'Invalid input', description: err.message, type: "error" }), + InvalidArgument: (err) => toastManager.add({ title: 'Invalid input', description: err.rawMessage, type: "error" }), PermissionDenied: () => toastManager.add({ title: "You don't have permission to perform this action", type: "error" }), - Default: (err) => toastManager.add({ title: 'Something went wrong', description: err.message, type: "error" }), + Default: (err) => toastManager.add({ title: 'Something went wrong', description: err.rawMessage, type: "error" }), }); } };