diff --git a/src/frontend/src/components/buttons/PrintingActions.tsx b/src/frontend/src/components/buttons/PrintingActions.tsx
index 1dede788a4..68e0e432c6 100644
--- a/src/frontend/src/components/buttons/PrintingActions.tsx
+++ b/src/frontend/src/components/buttons/PrintingActions.tsx
@@ -72,9 +72,6 @@ export function PrintingActions({
.then((response: any) => {
return extractAvailableFields(response, 'POST') || {};
})
- .catch(() => {
- return {};
- })
});
const labelFields: ApiFormFieldSet = useMemo(() => {
diff --git a/src/frontend/src/components/dashboard/DashboardLayout.tsx b/src/frontend/src/components/dashboard/DashboardLayout.tsx
index aa031fa081..0a0d02aa3c 100644
--- a/src/frontend/src/components/dashboard/DashboardLayout.tsx
+++ b/src/frontend/src/components/dashboard/DashboardLayout.tsx
@@ -1,7 +1,7 @@
import { t } from '@lingui/core/macro';
import { Alert, Card, Center, Divider, Loader, Text } from '@mantine/core';
import { useDisclosure, useHotkeys } from '@mantine/hooks';
-import { IconInfoCircle } from '@tabler/icons-react';
+import { IconExclamationCircle, IconInfoCircle } from '@tabler/icons-react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { type Layout, Responsive, WidthProvider } from 'react-grid-layout';
@@ -220,6 +220,11 @@ export default function DashboardLayout() {
removing={removing}
/>
+ {availableWidgets.error && (
+ }>
+ {t`Failed to load dashboard widgets.`}
+
+ )}
{layouts && loaded && availableWidgets.loaded ? (
<>
{widgetLabels.length == 0 ? (
diff --git a/src/frontend/src/components/dashboard/widgets/QueryCountDashboardWidget.tsx b/src/frontend/src/components/dashboard/widgets/QueryCountDashboardWidget.tsx
index 839ecc3a6d..3db70f530b 100644
--- a/src/frontend/src/components/dashboard/widgets/QueryCountDashboardWidget.tsx
+++ b/src/frontend/src/components/dashboard/widgets/QueryCountDashboardWidget.tsx
@@ -47,8 +47,7 @@ function QueryCountWidget({
limit: 1
}
})
- .then((res) => res.data)
- .catch(() => {});
+ .then((res) => res.data);
}
});
diff --git a/src/frontend/src/components/details/Details.tsx b/src/frontend/src/components/details/Details.tsx
index 546d4b87a0..4866f8c773 100644
--- a/src/frontend/src/components/details/Details.tsx
+++ b/src/frontend/src/components/details/Details.tsx
@@ -196,19 +196,14 @@ function NameBadge({
const url = apiUrl(path, pk);
- return api
- .get(url)
- .then((response) => {
- switch (response.status) {
- case 200:
- return response.data;
- default:
- return {};
- }
- })
- .catch(() => {
- return {};
- });
+ return api.get(url).then((response) => {
+ switch (response.status) {
+ case 200:
+ return response.data;
+ default:
+ return {};
+ }
+ });
}
});
@@ -356,9 +351,6 @@ function TableAnchorValue(props: Readonly) {
default:
return {};
}
- })
- .catch(() => {
- return {};
});
}
});
diff --git a/src/frontend/src/components/editors/NotesEditor.tsx b/src/frontend/src/components/editors/NotesEditor.tsx
index 418ca065d7..667cdd1ae5 100644
--- a/src/frontend/src/components/editors/NotesEditor.tsx
+++ b/src/frontend/src/components/editors/NotesEditor.tsx
@@ -92,11 +92,9 @@ export default function NotesEditor({
const dataQuery = useQuery({
queryKey: ['notes-editor', noteUrl, modelType, modelId],
+ retry: 5,
queryFn: () =>
- api
- .get(noteUrl)
- .then((response) => response.data?.notes ?? '')
- .catch(() => ''),
+ api.get(noteUrl).then((response) => response.data?.notes ?? ''),
enabled: true
});
diff --git a/src/frontend/src/components/forms/ApiForm.tsx b/src/frontend/src/components/forms/ApiForm.tsx
index 01d409a2cf..3efe39057e 100644
--- a/src/frontend/src/components/forms/ApiForm.tsx
+++ b/src/frontend/src/components/forms/ApiForm.tsx
@@ -254,19 +254,14 @@ export function ApiForm({
props.pathParams
],
queryFn: async () => {
- return await api
- .get(url)
- .then((response: any) => {
- // Process API response
- const fetchedData: any = processFields(fields, response.data);
+ return await api.get(url).then((response: any) => {
+ // Process API response
+ const fetchedData: any = processFields(fields, response.data);
- // Update form values, but only for the fields specified for this form
- form.reset(fetchedData);
- return fetchedData;
- })
- .catch(() => {
- return {};
- });
+ // Update form values, but only for the fields specified for this form
+ form.reset(fetchedData);
+ return fetchedData;
+ });
}
});
diff --git a/src/frontend/src/components/forms/fields/RelatedModelField.tsx b/src/frontend/src/components/forms/fields/RelatedModelField.tsx
index 1b77da0d89..1fb18c0b31 100644
--- a/src/frontend/src/components/forms/fields/RelatedModelField.tsx
+++ b/src/frontend/src/components/forms/fields/RelatedModelField.tsx
@@ -179,10 +179,6 @@ export function RelatedModelField({
setData(values);
dataRef.current = values;
return response;
- })
- .catch((error) => {
- setData([]);
- return error;
});
}
});
diff --git a/src/frontend/src/components/modals/LicenseModal.tsx b/src/frontend/src/components/modals/LicenseModal.tsx
index cdd1d86a62..1625178138 100644
--- a/src/frontend/src/components/modals/LicenseModal.tsx
+++ b/src/frontend/src/components/modals/LicenseModal.tsx
@@ -57,10 +57,7 @@ export function LicenseModal() {
queryKey: ['license'],
refetchOnMount: true,
queryFn: () =>
- api
- .get(apiUrl(ApiEndpoints.license))
- .then((res) => res.data ?? {})
- .catch(() => {})
+ api.get(apiUrl(ApiEndpoints.license)).then((res) => res.data ?? {})
});
const packageKeys = useMemo(() => {
diff --git a/src/frontend/src/components/nav/Header.tsx b/src/frontend/src/components/nav/Header.tsx
index d843b3ffc5..4e08ca07a6 100644
--- a/src/frontend/src/components/nav/Header.tsx
+++ b/src/frontend/src/components/nav/Header.tsx
@@ -78,23 +78,17 @@ export function Header() {
return null;
}
- try {
- const params = {
+ return api
+ .get(apiUrl(ApiEndpoints.notifications_list), {
params: {
read: false,
limit: 1
}
- };
- const response = await api
- .get(apiUrl(ApiEndpoints.notifications_list), params)
- .catch(() => {
- return null;
- });
- setNotificationCount(response?.data?.count ?? 0);
- return response?.data ?? null;
- } catch (error) {
- return null;
- }
+ })
+ .then((response: any) => {
+ setNotificationCount(response?.data?.count ?? 0);
+ return response.data ?? null;
+ });
},
// Refetch every minute, *if* the tab is visible
refetchInterval: 60 * 1000,
diff --git a/src/frontend/src/components/nav/NavigationTree.tsx b/src/frontend/src/components/nav/NavigationTree.tsx
index 1840d8ca6a..b3ff275197 100644
--- a/src/frontend/src/components/nav/NavigationTree.tsx
+++ b/src/frontend/src/components/nav/NavigationTree.tsx
@@ -1,5 +1,6 @@
import {
ActionIcon,
+ Alert,
Anchor,
Divider,
Drawer,
@@ -15,6 +16,7 @@ import {
import {
IconChevronDown,
IconChevronRight,
+ IconExclamationCircle,
IconSitemap
} from '@tabler/icons-react';
import { useQuery } from '@tanstack/react-query';
@@ -29,6 +31,7 @@ import {
getDetailUrl,
navigateToLink
} from '@lib/functions/Navigation';
+import { t } from '@lingui/core/macro';
import { useApi } from '../../contexts/ApiContext';
import { ApiIcon } from '../items/ApiIcon';
import { StylishText } from '../items/StylishText';
@@ -67,10 +70,6 @@ export default function NavigationTree({
}
})
.then((response) => response.data ?? [])
- .catch((error) => {
- console.error(`Error fetching ${modelType} tree`);
- return [];
- })
});
const follow = useCallback(
@@ -96,7 +95,7 @@ export default function NavigationTree({
const nodes: Record = {};
const tree: TreeNodeData[] = [];
- if (!query?.data?.length) {
+ if (!query || !query?.data?.length) {
return [];
}
@@ -207,7 +206,13 @@ export default function NavigationTree({
-
+ {query.isError ? (
+ }>
+ {t`Error loading navigation tree.`}
+
+ ) : (
+
+ )}
);
diff --git a/src/frontend/src/components/nav/NotificationDrawer.tsx b/src/frontend/src/components/nav/NotificationDrawer.tsx
index 33b022c933..ee5901c428 100644
--- a/src/frontend/src/components/nav/NotificationDrawer.tsx
+++ b/src/frontend/src/components/nav/NotificationDrawer.tsx
@@ -122,10 +122,7 @@ export function NotificationDrawer({
ordering: '-creation'
}
})
- .then((response) => response.data)
- .catch((error) => {
- return error;
- }),
+ .then((response) => response.data),
refetchOnMount: false
});
diff --git a/src/frontend/src/components/nav/SearchDrawer.tsx b/src/frontend/src/components/nav/SearchDrawer.tsx
index 3c4198b93e..c3ecf0f5d8 100644
--- a/src/frontend/src/components/nav/SearchDrawer.tsx
+++ b/src/frontend/src/components/nav/SearchDrawer.tsx
@@ -397,11 +397,7 @@ export function SearchDrawer({
return api
.post(apiUrl(ApiEndpoints.api_search), params)
- .then((response) => response.data)
- .catch((error) => {
- console.error(error);
- return [];
- });
+ .then((response) => response.data);
};
// Search query manager
diff --git a/src/frontend/src/components/render/Instance.tsx b/src/frontend/src/components/render/Instance.tsx
index 006256fc6f..50b4e2f2e9 100644
--- a/src/frontend/src/components/render/Instance.tsx
+++ b/src/frontend/src/components/render/Instance.tsx
@@ -137,10 +137,7 @@ export function RenderRemoteInstance({
queryFn: async () => {
const url = apiUrl(ModelInformationDict[model].api_endpoint, pk);
- return api
- .get(url)
- .then((response) => response.data)
- .catch(() => null);
+ return api.get(url).then((response) => response.data);
}
});
diff --git a/src/frontend/src/forms/StockForms.tsx b/src/frontend/src/forms/StockForms.tsx
index dad409597d..cd393e61af 100644
--- a/src/frontend/src/forms/StockForms.tsx
+++ b/src/frontend/src/forms/StockForms.tsx
@@ -1100,10 +1100,7 @@ function useStockOperationModal({
.get(url, {
params: params
})
- .then((response) => response.data ?? [])
- .catch(() => {
- return [];
- });
+ .then((response) => response.data ?? []);
}
});
@@ -1368,7 +1365,7 @@ export function useFindSerialNumberForm({
}
},
checkClose: (data, form) => {
- if (data.length == 0) {
+ if (!data || data?.length == 0) {
form.setError('serial', { message: t`No matching items` });
return false;
}
diff --git a/src/frontend/src/functions/api.tsx b/src/frontend/src/functions/api.tsx
index 7aea6e862d..7fb2a14da1 100644
--- a/src/frontend/src/functions/api.tsx
+++ b/src/frontend/src/functions/api.tsx
@@ -15,7 +15,7 @@ export function extractErrorMessage({
field?: string;
defaultMessage?: string;
}): string {
- const error_data = error.response?.data ?? null;
+ const error_data = error.response?.data ?? error.data ?? null;
let message = '';
@@ -25,7 +25,7 @@ export function extractErrorMessage({
// No message? Look at the response status codes
if (!message) {
- const status = error.response?.status ?? null;
+ const status = error.status ?? error.response?.status ?? null;
if (status) {
switch (status) {
@@ -48,8 +48,11 @@ export function extractErrorMessage({
message = t`Internal server error`;
break;
default:
+ message = t`Unknown error`;
break;
}
+
+ message = `${status} - ${message}`;
}
}
diff --git a/src/frontend/src/functions/notifications.tsx b/src/frontend/src/functions/notifications.tsx
index 4e471e61cc..90fc97ba68 100644
--- a/src/frontend/src/functions/notifications.tsx
+++ b/src/frontend/src/functions/notifications.tsx
@@ -80,12 +80,14 @@ export function showApiErrorMessage({
error,
title,
message,
- field
+ field,
+ id
}: {
error: any;
title: string;
message?: string;
field?: string;
+ id?: string;
}) {
const errorMessage = extractErrorMessage({
error: error,
@@ -93,7 +95,10 @@ export function showApiErrorMessage({
defaultMessage: message
});
+ notifications.hide(id ?? 'api-error');
+
notifications.show({
+ id: id ?? 'api-error',
title: title,
message: errorMessage,
color: 'red'
diff --git a/src/frontend/src/hooks/UseCalendar.tsx b/src/frontend/src/hooks/UseCalendar.tsx
index 7335ea28cc..f7867eb0e3 100644
--- a/src/frontend/src/hooks/UseCalendar.tsx
+++ b/src/frontend/src/hooks/UseCalendar.tsx
@@ -103,6 +103,14 @@ export default function useCalendar({
const query = useQuery({
enabled: !!startDate && !!endDate,
queryKey: ['calendar', name, endpoint, queryFilters],
+ throwOnError: (error: any) => {
+ showApiErrorMessage({
+ error: error,
+ title: 'Error fetching calendar data'
+ });
+
+ return true;
+ },
queryFn: async () => {
// Fetch data from the API
return api
@@ -111,12 +119,6 @@ export default function useCalendar({
})
.then((response) => {
return response.data ?? [];
- })
- .catch((error) => {
- showApiErrorMessage({
- error: error,
- title: 'Error fetching calendar data'
- });
});
}
});
@@ -173,6 +175,6 @@ export default function useCalendar({
setEndDate,
exportModal,
query: query,
- data: query.data
+ data: query.data ?? []
};
}
diff --git a/src/frontend/src/hooks/UseDashboardItems.tsx b/src/frontend/src/hooks/UseDashboardItems.tsx
index dae1fcb9e0..f7f7e34c94 100644
--- a/src/frontend/src/hooks/UseDashboardItems.tsx
+++ b/src/frontend/src/hooks/UseDashboardItems.tsx
@@ -19,6 +19,7 @@ import { useUserState } from '../states/UserState';
interface DashboardLibraryProps {
items: DashboardWidgetProps[];
loaded: boolean;
+ error: any;
}
/**
@@ -51,13 +52,7 @@ export function useDashboardItems(): DashboardLibraryProps {
feature_type: PluginUIFeatureType.dashboard
});
- return api
- .get(url)
- .then((response: any) => response.data)
- .catch((_error: any) => {
- console.error('ERR: Failed to fetch plugin dashboard items');
- return [];
- });
+ return api.get(url).then((response: any) => response.data);
}
});
@@ -90,7 +85,7 @@ export function useDashboardItems(): DashboardLibraryProps {
};
}) ?? []
);
- }, [pluginQuery, inventreeContext]);
+ }, [pluginQuery.data, inventreeContext]);
const items: DashboardWidgetProps[] = useMemo(() => {
const widgets = [...builtin, ...pluginDashboardItems];
@@ -113,6 +108,7 @@ export function useDashboardItems(): DashboardLibraryProps {
return {
items: items,
- loaded: loaded
+ loaded: loaded,
+ error: pluginQuery.error
};
}
diff --git a/src/frontend/src/hooks/UseDataExport.tsx b/src/frontend/src/hooks/UseDataExport.tsx
index 18465b5215..653a79beb3 100644
--- a/src/frontend/src/hooks/UseDataExport.tsx
+++ b/src/frontend/src/hooks/UseDataExport.tsx
@@ -72,9 +72,6 @@ export default function useDataExport({
.then((response: any) => {
return extractAvailableFields(response, 'GET') || {};
})
- .catch(() => {
- return {};
- })
});
// Construct a field set for the export form
diff --git a/src/frontend/src/hooks/UseFilter.tsx b/src/frontend/src/hooks/UseFilter.tsx
index 31ad5ed244..b4b5693f74 100644
--- a/src/frontend/src/hooks/UseFilter.tsx
+++ b/src/frontend/src/hooks/UseFilter.tsx
@@ -39,8 +39,7 @@ export function useFilters(props: UseFilterProps) {
}
return data;
- })
- .catch((error) => []);
+ });
}
});
diff --git a/src/frontend/src/hooks/UseGenerator.tsx b/src/frontend/src/hooks/UseGenerator.tsx
index c22da48931..3bfa6451f7 100644
--- a/src/frontend/src/hooks/UseGenerator.tsx
+++ b/src/frontend/src/hooks/UseGenerator.tsx
@@ -85,6 +85,13 @@ export function useGenerator(props: GeneratorProps): GeneratorState {
],
refetchOnMount: false,
refetchOnWindowFocus: false,
+ throwOnError: (error: any) => {
+ console.error(
+ `Error generating ${props.key} @ ${props.endpoint}:`,
+ error
+ );
+ return false;
+ },
queryFn: async () => {
const generatorQuery = {
...(props.initialQuery ?? {}),
@@ -105,14 +112,6 @@ export function useGenerator(props: GeneratorProps): GeneratorState {
props.onGenerate?.(value);
return response;
- })
- .catch((error) => {
- console.error(
- `Error generating ${props.key} @ ${props.endpoint}:`,
- error
- );
-
- return null;
});
}
});
diff --git a/src/frontend/src/hooks/UsePluginPanels.tsx b/src/frontend/src/hooks/UsePluginPanels.tsx
index 6418fcd1aa..2dcc367e10 100644
--- a/src/frontend/src/hooks/UsePluginPanels.tsx
+++ b/src/frontend/src/hooks/UsePluginPanels.tsx
@@ -53,6 +53,10 @@ export function usePluginPanels({
const pluginQuery = useQuery({
enabled: pluginPanelsEnabled && !!model && id !== undefined,
queryKey: ['custom-plugin-panels', model, id],
+ throwOnError: (error: any) => {
+ console.error('ERR: Failed to fetch plugin panels');
+ return false;
+ },
queryFn: async () => {
if (!pluginPanelsEnabled || !model) {
return Promise.resolve([]);
@@ -69,11 +73,7 @@ export function usePluginPanels({
target_id: id
}
})
- .then((response: any) => response.data)
- .catch((_error: any) => {
- console.error('ERR: Failed to fetch plugin panels');
- return [];
- });
+ .then((response: any) => response.data);
}
});
diff --git a/src/frontend/src/pages/part/PartDetail.tsx b/src/frontend/src/pages/part/PartDetail.tsx
index b575278130..4b4d7363bd 100644
--- a/src/frontend/src/pages/part/PartDetail.tsx
+++ b/src/frontend/src/pages/part/PartDetail.tsx
@@ -723,8 +723,7 @@ export default function PartDetail() {
default:
break;
}
- })
- .catch(() => {});
+ });
return revisions;
}
diff --git a/src/frontend/src/pages/stock/StockDetail.tsx b/src/frontend/src/pages/stock/StockDetail.tsx
index 49bab78ad9..56274de468 100644
--- a/src/frontend/src/pages/stock/StockDetail.tsx
+++ b/src/frontend/src/pages/stock/StockDetail.tsx
@@ -491,9 +491,6 @@ export default function StockDetail() {
} else {
return null;
}
- })
- .catch(() => {
- return null;
});
}
});
@@ -504,7 +501,7 @@ export default function StockDetail() {
return true;
}
- if (trackedBomItemQuery.data != null) {
+ if (!!trackedBomItemQuery.data) {
return trackedBomItemQuery.data;
}
diff --git a/src/frontend/src/tables/InvenTreeTable.tsx b/src/frontend/src/tables/InvenTreeTable.tsx
index 10fc744344..a89259c45e 100644
--- a/src/frontend/src/tables/InvenTreeTable.tsx
+++ b/src/frontend/src/tables/InvenTreeTable.tsx
@@ -28,12 +28,12 @@ import { navigateToLink } from '@lib/functions/Navigation';
import type { TableFilter } from '@lib/types/Filters';
import type { ApiFormFieldSet } from '@lib/types/Forms';
import type { TableState } from '@lib/types/Tables';
-import { hideNotification, showNotification } from '@mantine/notifications';
import { IconArrowRight } from '@tabler/icons-react';
import { Boundary } from '../components/Boundary';
import { useApi } from '../contexts/ApiContext';
import { resolveItem } from '../functions/conversion';
import { extractAvailableFields, mapFields } from '../functions/forms';
+import { showApiErrorMessage } from '../functions/notifications';
import { useLocalState } from '../states/LocalState';
import type { TableColumn } from './Column';
import InvenTreeTableHeader from './InvenTreeTableHeader';
@@ -199,7 +199,16 @@ export function InvenTreeTable>({
tableProps.params,
props.enableColumnCaching
],
- retry: 3,
+ retry: 5,
+ retryDelay: (attempt: number) => (1 + attempt) * 250,
+ throwOnError: (error: any) => {
+ showApiErrorMessage({
+ error: error,
+ title: t`Error loading table options`
+ });
+
+ return true;
+ },
refetchOnMount: true,
gcTime: 5000,
queryFn: async () => {
@@ -240,17 +249,6 @@ export function InvenTreeTable>({
setTableColumnNames(cacheKey)(names);
}
- return null;
- })
- .catch(() => {
- hideNotification('table-options-error');
- showNotification({
- id: 'table-options-error',
- title: t`API Error`,
- message: t`Failed to load table options`,
- color: 'red'
- });
-
return null;
});
}
@@ -270,9 +268,7 @@ export function InvenTreeTable>({
setFieldNames(cachedNames);
return;
}
-
- tableOptionQuery.refetch();
- }, [cacheKey, url, props.params, props.enableColumnCaching]);
+ }, []);
const enableSelection: boolean = useMemo(() => {
return tableProps.enableSelection || tableProps.enableBulkDelete || false;
@@ -555,54 +551,24 @@ export function InvenTreeTable>({
return api
.get(url, {
params: queryParams,
- timeout: 5 * 1000
+ timeout: 10 * 1000
})
.then((response) => {
- switch (response.status) {
- case 200:
- setMissingRecordsText(
- tableProps.noRecordsText ?? t`No records found`
- );
+ let results = response.data?.results ?? response.data ?? [];
- let results = response.data?.results ?? response.data ?? [];
-
- if (props.dataFormatter) {
- // Custom data formatter provided
- results = props.dataFormatter(results);
- }
-
- if (!Array.isArray(results)) {
- setMissingRecordsText(t`Server returned incorrect data type`);
- results = [];
- }
-
- tableState.setRecordCount(response.data?.count ?? results.length);
-
- return results;
- case 400:
- setMissingRecordsText(t`Bad request`);
- break;
- case 401:
- setMissingRecordsText(t`Unauthorized`);
- break;
- case 403:
- setMissingRecordsText(t`Forbidden`);
- break;
- case 404:
- setMissingRecordsText(t`Not found`);
- break;
- default:
- setMissingRecordsText(
- `${t`Unknown error`}: ${response.statusText}`
- );
- break;
+ if (props.dataFormatter) {
+ // Custom data formatter provided
+ results = props.dataFormatter(results);
}
- return [];
- })
- .catch((error) => {
- setMissingRecordsText(`${t`Error`}: ${error.message}`);
- return [];
+ if (!Array.isArray(results)) {
+ setMissingRecordsText(t`Server returned incorrect data type`);
+ results = [];
+ }
+
+ tableState.setRecordCount(response.data?.count ?? results.length);
+
+ return results;
});
};
@@ -626,9 +592,18 @@ export function InvenTreeTable>({
tableState.storedDataLoaded,
tableState.searchTerm
],
+ retry: 5,
+ retryDelay: (attempt: number) => (1 + attempt) * 250,
+ throwOnError: (error: any) => {
+ showApiErrorMessage({
+ error: error,
+ title: t`Error loading table data`
+ });
+
+ return true;
+ },
enabled: !!url && !tableData && tableState.storedDataLoaded,
- queryFn: fetchTableData,
- refetchOnMount: true
+ queryFn: fetchTableData
});
// Refetch data when the query parameters change
diff --git a/src/frontend/src/tables/build/BuildOrderTestTable.tsx b/src/frontend/src/tables/build/BuildOrderTestTable.tsx
index dbfa6ac688..626e713f2c 100644
--- a/src/frontend/src/tables/build/BuildOrderTestTable.tsx
+++ b/src/frontend/src/tables/build/BuildOrderTestTable.tsx
@@ -53,8 +53,7 @@ export default function BuildOrderTestTable({
required: true
}
})
- .then((res) => res.data)
- .catch((err) => []);
+ .then((res) => res.data);
}
});
diff --git a/src/frontend/src/tables/build/BuildOutputTable.tsx b/src/frontend/src/tables/build/BuildOutputTable.tsx
index 59aadfe8e4..8b4fd05a84 100644
--- a/src/frontend/src/tables/build/BuildOutputTable.tsx
+++ b/src/frontend/src/tables/build/BuildOutputTable.tsx
@@ -160,8 +160,7 @@ export default function BuildOutputTable({
required: true
}
})
- .then((response) => response.data)
- .catch(() => []);
+ .then((response) => response.data);
}
});
@@ -184,8 +183,7 @@ export default function BuildOutputTable({
tracked: true
}
})
- .then((response) => response.data)
- .catch(() => []);
+ .then((response) => response.data);
}
});
diff --git a/src/frontend/src/tables/part/ParametricPartTable.tsx b/src/frontend/src/tables/part/ParametricPartTable.tsx
index 6269010352..01e0f1321f 100644
--- a/src/frontend/src/tables/part/ParametricPartTable.tsx
+++ b/src/frontend/src/tables/part/ParametricPartTable.tsx
@@ -113,8 +113,7 @@ export default function ParametricPartTable({
category: categoryId
}
})
- .then((response) => response.data)
- .catch((_error) => []);
+ .then((response) => response.data);
},
refetchOnMount: true
});
@@ -290,7 +289,7 @@ export default function ParametricPartTable({
);
const parameterColumns: TableColumn[] = useMemo(() => {
- const data = categoryParameters.data ?? [];
+ const data = categoryParameters?.data || [];
return data.map((template: any) => {
let title = template.name;
diff --git a/src/frontend/src/tables/part/PartThumbTable.tsx b/src/frontend/src/tables/part/PartThumbTable.tsx
index 78bdfc657b..f69d8ac8a5 100644
--- a/src/frontend/src/tables/part/PartThumbTable.tsx
+++ b/src/frontend/src/tables/part/PartThumbTable.tsx
@@ -137,6 +137,11 @@ export function PartThumbTable({ pk, setImage }: Readonly) {
// Fetch thumbnails from API
const thumbQuery = useQuery({
queryKey: [ApiEndpoints.part_thumbs_list, page, searchText],
+ throwOnError: (error: any) => {
+ setTotalPages(1);
+ setPage(1);
+ return true;
+ },
queryFn: async () => {
const offset = Math.max(0, page - 1) * limit;
@@ -152,11 +157,6 @@ export function PartThumbTable({ pk, setImage }: Readonly) {
const records = response?.data?.count ?? 1;
setTotalPages(Math.ceil(records / limit));
return response.data?.results ?? response.data;
- })
- .catch((error) => {
- setTotalPages(1);
- setPage(1);
- return [];
});
}
});
@@ -172,7 +172,7 @@ export function PartThumbTable({ pk, setImage }: Readonly) {
spacing='xs'
>
{!thumbQuery.isFetching
- ? thumbQuery?.data.map((data: ImageElement, index: number) => (
+ ? thumbQuery?.data?.map((data: ImageElement, index: number) => (
response.data)
- .catch((_error) => []);
+ .then((response) => response.data);
}
});
@@ -85,13 +84,14 @@ export default function StockItemTestResultTable({
const formatRecords = useCallback(
(records: any[]): any[] => {
// Construct a list of test templates
- const results = testTemplates.map((template: any) => {
- return {
- ...template,
- templateId: template.pk,
- results: []
- };
- });
+ const results =
+ testTemplates?.map((template: any) => {
+ return {
+ ...template,
+ templateId: template.pk,
+ results: []
+ };
+ }) ?? [];
// If any of the tests results point to templates which we do not have, add them in
records.forEach((record) => {