diff --git a/app/components/CategoryModal/index.tsx b/app/components/CategoryModal/index.tsx index bb1668b..6a40f42 100644 --- a/app/components/CategoryModal/index.tsx +++ b/app/components/CategoryModal/index.tsx @@ -26,6 +26,7 @@ import { isDefined, isNotDefined, } from '@togglecorp/fujs'; +import type { CombinedError } from 'urql'; import { type ThematicAreasQuery, @@ -38,8 +39,9 @@ import useAlert from '#hooks/useAlert'; import useFilterState from '#hooks/useFilterState'; import { errorMessage, + getErrorMessage, idSelector, - transformToFormError, + type ServerError, } from '#utils/common'; type ThematicArea = NonNullable['results'][number]>; @@ -150,15 +152,13 @@ function CategoryModal(props: Props) { const handleResult = useCallback(( result: { ok?: boolean | null; errors?: unknown } | null | undefined, successMessage: string, + mutationError?: CombinedError, ) => { if (!result?.ok) { - const serverErrors = isDefined(result?.errors) - ? transformToFormError(result?.errors as Parameters[0]) - : undefined; - const messages = serverErrors - ? Object.values(serverErrors).filter(isDefined).join(' ') - : undefined; - alert.show(messages || errorMessage, { variant: 'danger' }); + alert.show( + getErrorMessage(mutationError, result?.errors as ServerError[] | null), + { variant: 'danger' }, + ); return; } setCategoryName(undefined); @@ -216,7 +216,7 @@ function CategoryModal(props: Props) { } setDeletingId(undefined); deleteThematicArea({ id: deletingId }).then((resp) => { - handleResult(resp.data?.deleteThematicArea, 'Category deleted successfully'); + handleResult(resp.data?.deleteThematicArea, 'Category deleted successfully', resp.error); }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); }); diff --git a/app/components/CategoryModal/query.ts b/app/components/CategoryModal/query.ts index 9cdd157..41f9daa 100644 --- a/app/components/CategoryModal/query.ts +++ b/app/components/CategoryModal/query.ts @@ -48,13 +48,8 @@ const UPDATE_THEMATIC_AREA = gql` const DELETE_THEMATIC_AREA = gql` mutation DeleteThematicArea($id: ID!) { deleteThematicArea(id: $id) { - ... on ThematicAreaTypeMutationResponseType { - errors - ok - result { - id - } - } + errors + ok } } `; diff --git a/app/utils/common.ts b/app/utils/common.ts index 6d57b98..33df852 100644 --- a/app/utils/common.ts +++ b/app/utils/common.ts @@ -1,4 +1,5 @@ import { + isDefined, isFalsyString, isNotDefined, } from '@togglecorp/fujs'; @@ -50,8 +51,17 @@ export const statusFilterOptions = [ export const errorMessage = 'Something went wrong. Please try again. '; -export function getErrorMessage(error: CombinedError | undefined) { - return error?.graphQLErrors?.[0]?.message || errorMessage; +// Mutations report failures on the payload's `errors`, not on the top-level GraphQL +// errors, so prefer those messages and fall back to the transport error. +export function getErrorMessage( + error: CombinedError | undefined, + serverErrors?: ServerError[] | null, +) { + const messages = serverErrors + ?.map((serverError) => serverError.messages) + .filter(isDefined) + .join(' '); + return messages || error?.graphQLErrors?.[0]?.message || errorMessage; } export function getReadableFileSize(bytes: number | null | undefined): string { @@ -105,7 +115,7 @@ export function validateFile(file: File, maxSize: number, accept: string | undef return undefined; } -interface ServerError { +export interface ServerError { field: string; messages: string | null; objectErrors?: ServerError[] | null; diff --git a/app/views/CapacityAndResources/ResourceDashboards/index.tsx b/app/views/CapacityAndResources/ResourceDashboards/index.tsx index fc30fb0..5743179 100644 --- a/app/views/CapacityAndResources/ResourceDashboards/index.tsx +++ b/app/views/CapacityAndResources/ResourceDashboards/index.tsx @@ -135,7 +135,7 @@ function ResourceDashboards() { } alert.show('Dashboard deleted successfully', { variant: 'success' }); } else { - alert.show(getErrorMessage(resp.error), { variant: 'danger' }); + alert.show(getErrorMessage(resp.error, result?.errors), { variant: 'danger' }); } }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); diff --git a/app/views/CapacityAndResources/index.tsx b/app/views/CapacityAndResources/index.tsx index 4373246..9c9ee1b 100644 --- a/app/views/CapacityAndResources/index.tsx +++ b/app/views/CapacityAndResources/index.tsx @@ -102,7 +102,7 @@ function CapacityAndResourcesList() { } alert.show('Resource deleted successfully', { variant: 'success' }); } else { - alert.show(getErrorMessage(resp.error), { variant: 'danger' }); + alert.show(getErrorMessage(resp.error, result?.errors), { variant: 'danger' }); } }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); diff --git a/app/views/CapacityAndResources/query.ts b/app/views/CapacityAndResources/query.ts index bcc2031..1fdcd7d 100644 --- a/app/views/CapacityAndResources/query.ts +++ b/app/views/CapacityAndResources/query.ts @@ -22,13 +22,8 @@ const CAPACITY_AND_RESOURCES = gql` const DELETE_CAPACITY_AND_RESOURCE = gql` mutation DeleteCapacityAndResource($id: ID!) { deleteCapacityAndResource(id: $id) { - ... on CapacityAndResourceTypeMutationResponseType { - errors - ok - result { - id - } - } + errors + ok } } `; @@ -97,13 +92,8 @@ const RESOURCE_DASHBOARDS = gql` const DELETE_RESOURCE_DASHBOARD = gql` mutation DeleteResourceDashboard($id: ID!) { deleteExternalDashboard(id: $id) { - ... on ExternalDashboardTypeMutationResponseType { - errors - ok - result { - id - } - } + errors + ok } } `; diff --git a/app/views/DataAndReports/index.tsx b/app/views/DataAndReports/index.tsx index a57dc5e..b893eb7 100644 --- a/app/views/DataAndReports/index.tsx +++ b/app/views/DataAndReports/index.tsx @@ -38,6 +38,7 @@ import useRegionMap from '#hooks/useRegionMap'; import useRouting from '#hooks/useRouting'; import { errorMessage, + getErrorMessage, idSelector, } from '#utils/common'; @@ -121,7 +122,10 @@ function DataAndReports() { reExecuteQuery(); alert.show('Report deleted successfully', { variant: 'success' }); } else { - alert.show(errorMessage, { variant: 'danger' }); + alert.show( + getErrorMessage(resp.error, result?.errors), + { variant: 'danger' }, + ); } }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); diff --git a/app/views/DataAndReports/query.ts b/app/views/DataAndReports/query.ts index ba7d3d3..9405f73 100644 --- a/app/views/DataAndReports/query.ts +++ b/app/views/DataAndReports/query.ts @@ -24,13 +24,8 @@ const REPORTS = gql` const DELETE_REPORT = gql` mutation DeleteReport($id: ID!) { deleteReport(id: $id) { - ... on ReportTypeMutationResponseType { - errors - ok - result { - id - } - } + errors + ok } } `; diff --git a/app/views/Documents/query.ts b/app/views/Documents/query.ts index e0fa9cd..0f03fa7 100644 --- a/app/views/Documents/query.ts +++ b/app/views/Documents/query.ts @@ -19,13 +19,8 @@ const DOCUMENTS = gql` const DELETE_DOCUMENT = gql` mutation DeleteDocument($id: ID!) { deleteReport(id: $id) { - ... on ReportTypeMutationResponseType { - errors - ok - result { - id - } - } + errors + ok } } `; diff --git a/app/views/Galleries/query.ts b/app/views/Galleries/query.ts index 45dea4c..7b4391b 100644 --- a/app/views/Galleries/query.ts +++ b/app/views/Galleries/query.ts @@ -86,10 +86,8 @@ const CREATE_GALLERY_IMAGE = gql` const DELETE_GALLERY_IMAGE = gql` mutation DeleteGalleryImage($id: ID!) { deleteGalleryImage(id: $id) { - ... on GalleryImageTypeMutationResponseType { - errors - ok - } + errors + ok } } `; @@ -122,14 +120,8 @@ const UPDATE_GALLERY_ALBUM = gql` const DELETE_GALLERY_ALBUM = gql` mutation DeleteGalleryAlbum($id: ID!) { deleteGalleryAlbum(id: $id) { - ... on GalleryAlbumTypeMutationResponseType { - errors - ok - result { - id - title - } - } + errors + ok } } `; diff --git a/app/views/Home/index.tsx b/app/views/Home/index.tsx index fbd609d..be49e79 100644 --- a/app/views/Home/index.tsx +++ b/app/views/Home/index.tsx @@ -129,7 +129,7 @@ function Home() { reExecuteQuickLinksQuery(); alert.show('Added to quick links', { variant: 'success' }); } else { - alert.show(getErrorMessage(resp.error), { variant: 'danger' }); + alert.show(getErrorMessage(resp.error, result?.errors), { variant: 'danger' }); } }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); @@ -156,7 +156,7 @@ function Home() { reExecuteQuickLinksQuery(); alert.show('Removed from quick links', { variant: 'success' }); } else { - alert.show(getErrorMessage(resp.error), { variant: 'danger' }); + alert.show(getErrorMessage(resp.error, result?.errors), { variant: 'danger' }); } }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); diff --git a/app/views/Links/index.tsx b/app/views/Links/index.tsx index 55bf0ad..7acc230 100644 --- a/app/views/Links/index.tsx +++ b/app/views/Links/index.tsx @@ -117,7 +117,7 @@ function Links() { reExecuteQuery(); alert.show('Link deleted successfully', { variant: 'success' }); } else { - alert.show(getErrorMessage(resp.error), { variant: 'danger' }); + alert.show(getErrorMessage(resp.error, result?.errors), { variant: 'danger' }); } }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); diff --git a/app/views/Links/query.ts b/app/views/Links/query.ts index c2171ac..0271e46 100644 --- a/app/views/Links/query.ts +++ b/app/views/Links/query.ts @@ -63,14 +63,8 @@ const LINK_DETAILS = gql` const DELETE_LINK = gql` mutation DeleteLink($id: ID!) { deleteLink(id: $id) { - ... on LinkTypeMutationResponseType { - errors - ok - result { - id - title - } - } + errors + ok } } `; diff --git a/app/views/OnlineInteractive/query.ts b/app/views/OnlineInteractive/query.ts index e9fc04a..79f4aed 100644 --- a/app/views/OnlineInteractive/query.ts +++ b/app/views/OnlineInteractive/query.ts @@ -63,13 +63,8 @@ const UPDATE_ONLINE_INTERACTIVE = gql` const DELETE_ONLINE_INTERACTIVE = gql` mutation DeleteOnlineInteractive($id: ID!) { deleteReport(id: $id) { - ... on ReportTypeMutationResponseType { - errors - ok - result { - id - } - } + errors + ok } } `; diff --git a/app/views/OurWorks/index.tsx b/app/views/OurWorks/index.tsx index 1381cb3..811850d 100644 --- a/app/views/OurWorks/index.tsx +++ b/app/views/OurWorks/index.tsx @@ -130,7 +130,7 @@ function OurWorks() { } alert.show('Dashboard deleted successfully', { variant: 'success' }); } else { - alert.show(getErrorMessage(resp.error), { variant: 'danger' }); + alert.show(getErrorMessage(resp.error, result?.errors), { variant: 'danger' }); } }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); diff --git a/app/views/OurWorks/query.ts b/app/views/OurWorks/query.ts index 0f084c4..e8fbf5d 100644 --- a/app/views/OurWorks/query.ts +++ b/app/views/OurWorks/query.ts @@ -26,13 +26,8 @@ const EXTERNAL_DASHBOARDS = gql` const DELETE_EXTERNAL_DASHBOARD = gql` mutation DeleteExternalDashboard($id: ID!) { deleteExternalDashboard(id: $id) { - ... on ExternalDashboardTypeMutationResponseType { - errors - ok - result { - id - } - } + errors + ok } } `; diff --git a/app/views/Pmer/query.ts b/app/views/Pmer/query.ts index 543e827..81fada0 100644 --- a/app/views/Pmer/query.ts +++ b/app/views/Pmer/query.ts @@ -78,13 +78,8 @@ const UPDATE_PMER_REPORT = gql` const DELETE_PMER_REPORT = gql` mutation DeletePmerReport($id: ID!) { deletePmerReport(id: $id) { - ... on PmerReportTypeMutationResponseType { - errors - ok - result { - id - } - } + errors + ok } } `; diff --git a/app/views/Preparedness/index.tsx b/app/views/Preparedness/index.tsx index 6432445..2192812 100644 --- a/app/views/Preparedness/index.tsx +++ b/app/views/Preparedness/index.tsx @@ -128,7 +128,7 @@ function PreparednessList() { } alert.show('Dashboard deleted successfully', { variant: 'success' }); } else { - alert.show(getErrorMessage(resp.error), { variant: 'danger' }); + alert.show(getErrorMessage(resp.error, result?.errors), { variant: 'danger' }); } }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); diff --git a/app/views/Preparedness/query.ts b/app/views/Preparedness/query.ts index 0b52282..034a2bf 100644 --- a/app/views/Preparedness/query.ts +++ b/app/views/Preparedness/query.ts @@ -26,13 +26,8 @@ const EXTERNAL_DASHBOARDS = gql` const DELETE_EXTERNAL_DASHBOARD = gql` mutation PreparednessDeleteExternalDashboard($id: ID!) { deleteExternalDashboard(id: $id) { - ... on ExternalDashboardTypeMutationResponseType { - errors - ok - result { - id - } - } + errors + ok } } `; diff --git a/app/views/Teams/TeamMembers/index.tsx b/app/views/Teams/TeamMembers/index.tsx index ffa13ff..e0e30e6 100644 --- a/app/views/Teams/TeamMembers/index.tsx +++ b/app/views/Teams/TeamMembers/index.tsx @@ -111,7 +111,7 @@ function TeamMembers() { reExecuteQuery(); alert.show('Team member deleted successfully', { variant: 'success' }); } else { - alert.show(getErrorMessage(resp.error), { variant: 'danger' }); + alert.show(getErrorMessage(resp.error, result?.errors), { variant: 'danger' }); } }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); diff --git a/app/views/Teams/index.tsx b/app/views/Teams/index.tsx index 4c6571e..c843034 100644 --- a/app/views/Teams/index.tsx +++ b/app/views/Teams/index.tsx @@ -98,7 +98,7 @@ function Teams() { reExecuteQuery(); alert.show('Team deleted successfully', { variant: 'success' }); } else { - alert.show(getErrorMessage(resp.error), { variant: 'danger' }); + alert.show(getErrorMessage(resp.error, result?.errors), { variant: 'danger' }); } }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); diff --git a/app/views/Teams/query.ts b/app/views/Teams/query.ts index e404509..990ffbb 100644 --- a/app/views/Teams/query.ts +++ b/app/views/Teams/query.ts @@ -51,14 +51,8 @@ const UPDATE_TEAM_MUTATION = gql` const DELETE_TEAM = gql` mutation DeleteTeam($id: ID!) { deleteTeam(id: $id) { - ... on TeamTypeMutationResponseType { - errors - ok - result { - id - name - } - } + errors + ok } } `; @@ -105,14 +99,8 @@ const TEAM_MEMBER = gql` const DELETE_TEAM_MEMBER = gql` mutation DeleteTeamMember($id: ID!) { deleteTeamMember(id: $id) { - ... on TeamMemberTypeMutationResponseType { - errors - ok - result { - id - name - } - } + errors + ok } } `; diff --git a/app/views/Users/index.tsx b/app/views/Users/index.tsx index 577c9fd..7f13ca5 100644 --- a/app/views/Users/index.tsx +++ b/app/views/Users/index.tsx @@ -139,7 +139,7 @@ function UsersList() { reExecuteQuery(); alert.show('User deactivated successfully', { variant: 'success' }); } else { - alert.show(getErrorMessage(resp.error), { variant: 'danger' }); + alert.show(getErrorMessage(resp.error, result?.errors), { variant: 'danger' }); } }).catch(() => { alert.show(errorMessage, { variant: 'danger' }); diff --git a/app/views/Users/query.ts b/app/views/Users/query.ts index f4f5c11..c4b7e51 100644 --- a/app/views/Users/query.ts +++ b/app/views/Users/query.ts @@ -86,13 +86,8 @@ const UPDATE_USER_MUTATION = gql` const DELETE_USER = gql` mutation DeleteUser($id: ID!) { deleteUser(id: $id) { - ... on UserTypeMutationResponseType { - errors - ok - result { - id - } - } + errors + ok } } `; diff --git a/backend b/backend index 0351d5e..00087b3 160000 --- a/backend +++ b/backend @@ -1 +1 @@ -Subproject commit 0351d5e45164d199d1e50837949fb0512ad2717e +Subproject commit 00087b336201138fd1215d64677a6d9560f9175d