let inline error callers own mutation failures (#48640)

## What kind of change does this PR introduce?

Code clean-up following #48470, #48471, #48472, #48473, and #48474.

## What is the current behavior?

Mutation hooks provide fallback error toasts, so callers that already
render errors inline must suppress those toasts with empty `onError`
handlers.

## What is the new behavior?

The affected callers own their error presentation. Inline interstitial
errors remain unchanged, API authorisation retains its state-reset
handlers, and Project Claim retains its combined caller-owned toast.

## To test

There is no useful before-and-after visual check for this PR: the
rendered error states should be identical on `master` and this branch.
The change only removes the default-toast and no-op-handler pair
underneath the UI.

The existing [Organisation
Invite](https://github.com/supabase/supabase/pull/48470), [API
authorisation, AWS
Marketplace](https://github.com/supabase/supabase/pull/48471), and
[Stripe Projects](https://github.com/supabase/supabase/pull/48472)
failure tests cover the inline errors and confirm that no duplicate
toast appears.
This commit is contained in:
Danny White authored and GitHub committed 2026-08-06 16:06:38 +07:00
1 parent 93b5ae71bf
commit 840127cd69
9 files changed
+22 -72

No files matched your search

@@ -77,7 +77,6 @@ export const AwsMarketplaceOnboardingScreen = ({ buyerId }: { buyerId?: string }
onSuccess: (_, variables) => {
setLinkedOrgSlug(variables.slug)
},
onError: () => undefined,
})
const linkError = linkOrganizationError
? `Failed to link organization: ${linkOrganizationError.message}`
@@ -34,7 +34,7 @@ export const ProjectClaimConfirm = ({
const { invalidateProjectsQuery } = useInvalidateProjectsInfiniteQuery()
const { mutateAsync: approveRequest, isPending: isApproving } =
useApiAuthorizationApproveMutation({ onError: () => {} })
useApiAuthorizationApproveMutation()
const { mutateAsync: claimProject, isPending: isClaiming } = useOrganizationProjectClaimMutation()
@@ -78,8 +78,6 @@ export const OrganizationInvite = () => {
onSuccess: () => {
router.push('/organizations')
},
// [Joshen] Silence the default toast handler
onError: () => {},
})
async function handleJoinOrganization() {
@@ -1,5 +1,4 @@
import { useMutation } from '@tanstack/react-query'
import { toast } from 'sonner'
import { handleError, post } from '@/data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from '@/types'
@@ -29,26 +28,18 @@ export async function approveApiAuthorization({ id, slug }: ApiAuthorizationAppr
type ApiAuthorizationApproveData = Awaited<ReturnType<typeof approveApiAuthorization>>
export const useApiAuthorizationApproveMutation = ({
onError,
...options
}: Omit<
UseCustomMutationOptions<
ApiAuthorizationApproveData,
ResponseError,
ApiAuthorizationApproveVariables
>,
'mutationFn'
> = {}) => {
export const useApiAuthorizationApproveMutation = (
options: Omit<
UseCustomMutationOptions<
ApiAuthorizationApproveData,
ResponseError,
ApiAuthorizationApproveVariables
>,
'mutationFn'
> = {}
) => {
return useMutation<ApiAuthorizationApproveData, ResponseError, ApiAuthorizationApproveVariables>({
mutationFn: (vars) => approveApiAuthorization(vars),
async onError(data, variables, context) {
if (onError === undefined) {
toast.error(`Failed to approve authorization request: ${data.message}`)
} else {
onError(data, variables, context)
}
},
...options,
})
}
@@ -1,5 +1,4 @@
import { useMutation } from '@tanstack/react-query'
import { toast } from 'sonner'
import { del, handleError } from '@/data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from '@/types'
@@ -28,26 +27,18 @@ export async function declineApiAuthorization({ id, slug }: ApiAuthorizationDecl
type ApiAuthorizationDeclineData = Awaited<ReturnType<typeof declineApiAuthorization>>
export const useApiAuthorizationDeclineMutation = ({
onError,
...options
}: Omit<
UseCustomMutationOptions<
ApiAuthorizationDeclineData,
ResponseError,
ApiAuthorizationDeclineVariables
>,
'mutationFn'
> = {}) => {
export const useApiAuthorizationDeclineMutation = (
options: Omit<
UseCustomMutationOptions<
ApiAuthorizationDeclineData,
ResponseError,
ApiAuthorizationDeclineVariables
>,
'mutationFn'
> = {}
) => {
return useMutation<ApiAuthorizationDeclineData, ResponseError, ApiAuthorizationDeclineVariables>({
mutationFn: (vars) => declineApiAuthorization(vars),
async onError(data, variables, context) {
if (onError === undefined) {
toast.error(`Failed to decline authorization request: ${data.message}`)
} else {
onError(data, variables, context)
}
},
...options,
})
}
@@ -1,5 +1,4 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import { handleError, post } from '@/data/fetchers'
import { invalidateOrganizationsQuery } from '@/data/organizations/organizations-query'
@@ -28,7 +27,6 @@ type OrganizationMemberUpdateData = Awaited<ReturnType<typeof acceptOrganization
export const useOrganizationAcceptInvitationMutation = ({
onSuccess,
onError,
...options
}: Omit<
UseCustomMutationOptions<
@@ -55,13 +53,6 @@ export const useOrganizationAcceptInvitationMutation = ({
])
await onSuccess?.(data, variables, context)
},
async onError(data, variables, context) {
if (onError === undefined) {
toast.error(`Failed to accept invitation: ${data.message}`)
} else {
onError(data, variables, context)
}
},
...options,
})
}
@@ -1,5 +1,4 @@
import { useMutation } from '@tanstack/react-query'
import { toast } from 'sonner'
import { handleError, put } from '@/data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from '@/types'
@@ -26,7 +25,6 @@ type LinkOrganizationData = Awaited<ReturnType<typeof linkOrganization>>
export const useOrganizationLinkAwsMarketplaceMutation = ({
onSuccess,
onError,
...options
}: Omit<
UseCustomMutationOptions<
@@ -41,13 +39,6 @@ export const useOrganizationLinkAwsMarketplaceMutation = ({
async onSuccess(data, variables, context) {
await onSuccess?.(data, variables, context)
},
async onError(data, variables, context) {
if (onError === undefined) {
toast.error(`Failed to link organization to AWS Marketplace: ${data.message}`)
} else {
onError(data, variables, context)
}
},
...options,
})
}
@@ -1,5 +1,4 @@
import { useMutation } from '@tanstack/react-query'
import { toast } from 'sonner'
import { handleError, post } from '@/data/fetchers'
import type { ResponseError, UseCustomMutationOptions } from '@/types'
@@ -24,7 +23,6 @@ type ConfirmAccountRequestData = Awaited<ReturnType<typeof confirmAccountRequest
export const useConfirmAccountRequestMutation = ({
onSuccess,
onError,
...options
}: Omit<
UseCustomMutationOptions<
@@ -39,13 +37,6 @@ export const useConfirmAccountRequestMutation = ({
async onSuccess(data, variables, context) {
await onSuccess?.(data, variables, context)
},
async onError(data, variables, context) {
if (onError === undefined) {
toast.error(`Failed to confirm account request: ${data.message}`)
} else {
onError(data, variables, context)
}
},
...options,
})
}
@@ -51,9 +51,7 @@ export const StripeProjectsLoginPage: NextPageWithLayout = () => {
isSuccess: isConfirmationSuccess,
error: confirmationMutationError,
reset: resetConfirmationError,
} = useConfirmAccountRequestMutation({
onError: () => undefined,
})
} = useConfirmAccountRequestMutation()
const confirmationError = confirmationMutationError
? `Failed to authorize Stripe Projects: ${confirmationMutationError.message}`
: undefined