Skip to content

Commit 82c1d30

Browse files
authored
fix(extensions): show error when toggle fails (#2122)
1 parent 5ea0829 commit 82c1d30

File tree

5 files changed

+99
-13
lines changed

5 files changed

+99
-13
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@red-hat-developer-hub/backstage-plugin-extensions': patch
3+
---
4+
5+
show error in the UI when toggle action fails

workspaces/extensions/plugins/extensions/src/components/ExtensionsPackageEditContent.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import { TabPanel } from './TabPanel';
5555
import { useInstallationContext } from './InstallationContext';
5656
import { useTranslation } from '../hooks/useTranslation';
5757
import { ExtensionsStatus, getPluginActionTooltipMessage } from '../utils';
58+
import { InstallationWarning } from './InstallationWarning';
5859

5960
interface TabItem {
6061
label: string;
@@ -197,6 +198,13 @@ export const ExtensionsPackageEditContent = ({
197198

198199
const showRightCard = hasPackageExamples;
199200

201+
const showEditWarning =
202+
(pkgConfig.data as any)?.error?.message &&
203+
(pkgConfig.data as any)?.error?.reason !==
204+
ExtensionsStatus.INSTALLATION_DISABLED &&
205+
(pkgConfig.data as any)?.error?.reason !==
206+
ExtensionsStatus.INSTALLATION_DISABLED_IN_PRODUCTION;
207+
200208
const handleSave = async () => {
201209
try {
202210
setSaveError(null);
@@ -279,6 +287,12 @@ export const ExtensionsPackageEditContent = ({
279287

280288
return (
281289
<>
290+
{showEditWarning && <InstallationWarning configData={pkgConfig.data} />}
291+
{saveError && (
292+
<Alert severity="error" sx={{ mb: '1rem' }}>
293+
{saveError}
294+
</Alert>
295+
)}
282296
{!pkg.spec?.dynamicArtifact && (
283297
<Alert severity="error" sx={{ mb: '1rem' }}>
284298
<AlertTitle>{t('alert.missingDynamicArtifactTitle')}</AlertTitle>

workspaces/extensions/plugins/extensions/src/components/InstalledPackages/InstalledPackagesTable.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import { Query, QueryResult } from '@material-table/core';
2727
import { useQuery } from '@tanstack/react-query';
2828

2929
import Box from '@mui/material/Box';
30+
import Snackbar from '@mui/material/Snackbar';
31+
import Alert from '@mui/material/Alert';
3032
import {
3133
ExtensionsPackage,
3234
ExtensionsPackageInstallStatus,
@@ -58,6 +60,8 @@ import {
5860

5961
export const InstalledPackagesTable = () => {
6062
const { t } = useTranslation();
63+
const [rowActionError, setRowActionError] = useState<string | null>(null);
64+
const [snackbarOpen, setSnackbarOpen] = useState(false);
6165
const extensionsConfig = useExtensionsConfiguration();
6266
const { installedPackages } = useInstallationContext();
6367
const nodeEnvironment = useNodeEnvironment();
@@ -187,11 +191,19 @@ export const InstalledPackagesTable = () => {
187191
<DownloadPackageYaml
188192
pkg={row}
189193
isProductionEnv={isProductionEnvironment}
194+
onError={(err: string) => {
195+
setRowActionError(err);
196+
setSnackbarOpen(true);
197+
}}
190198
/>
191199
<TogglePackage
192200
pkg={row}
193201
isProductionEnv={isProductionEnvironment}
194202
isInstallationEnabled={extensionsConfig.data?.enabled ?? false}
203+
onError={(err: string) => {
204+
setRowActionError(err);
205+
setSnackbarOpen(true);
206+
}}
195207
/>
196208
</Box>
197209
);
@@ -359,6 +371,31 @@ export const InstalledPackagesTable = () => {
359371
onClose={setOpenInstalledPackagesDialog}
360372
showPackages
361373
/>
374+
<Snackbar
375+
open={snackbarOpen}
376+
autoHideDuration={6000}
377+
onClose={() => {
378+
setSnackbarOpen(false);
379+
setRowActionError(null);
380+
}}
381+
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
382+
sx={{
383+
top: '80px !important',
384+
}}
385+
>
386+
<Alert
387+
onClose={() => {
388+
setSnackbarOpen(false);
389+
setRowActionError(null);
390+
}}
391+
severity="error"
392+
sx={{ width: '100%' }}
393+
>
394+
{Array.isArray(rowActionError)
395+
? rowActionError.map((err, idx) => <div key={idx}>{err}</div>)
396+
: rowActionError}
397+
</Alert>
398+
</Snackbar>
362399
</>
363400
);
364401
};

workspaces/extensions/plugins/extensions/src/components/InstalledPackages/RowActions.tsx

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { ExtensionsPackageInstallStatus } from '@red-hat-developer-hub/backstage
3232
import { useTranslation } from '../../hooks/useTranslation';
3333
import { packageInstallRouteRef, packageRouteRef } from '../../routes';
3434
import { usePackageConfig } from '../../hooks/usePackageConfig';
35+
import { usePackage } from '../../hooks/usePackage';
3536
import { downloadPackageYAML } from '../../utils/downloadPackageYaml';
3637
import { usePluginConfigurationPermissions } from '../../hooks/usePluginConfigurationPermissions';
3738
import { useEnablePlugin } from '../../hooks/useEnablePlugin';
@@ -53,12 +54,15 @@ export type InstalledPackageRow = {
5354
export const DownloadPackageYaml = ({
5455
pkg,
5556
isProductionEnv,
57+
onError,
5658
}: {
5759
pkg: InstalledPackageRow;
5860
isProductionEnv: boolean;
61+
onError?: (error: string) => void;
5962
}) => {
6063
const { t } = useTranslation();
6164
const pkgConfig = usePackageConfig(pkg.namespace!, pkg.name!);
65+
const packageEntity = usePackage(pkg.namespace!, pkg.name!);
6266
const packageConfigPermission = usePluginConfigurationPermissions(
6367
pkg.namespace!,
6468
pkg.parentPlugin ?? '',
@@ -108,10 +112,31 @@ export const DownloadPackageYaml = ({
108112
size="small"
109113
sx={{ color: theme => theme.palette.text.primary }}
110114
onClick={async () => {
111-
await downloadPackageYAML(
112-
pkgConfig.data?.configYaml ?? '',
113-
pkg.name!,
114-
);
115+
try {
116+
const configYaml = pkgConfig.data?.configYaml ?? '';
117+
if (!configYaml) {
118+
const dynamicArtifact =
119+
packageEntity.data?.spec?.dynamicArtifact ??
120+
`./dynamic-plugins/dist/${pkg.packageName}`;
121+
const minimalYaml = `plugins:
122+
- package: ${JSON.stringify(dynamicArtifact)}
123+
disabled: false
124+
`;
125+
// eslint-disable-next-line no-console
126+
console.info(
127+
`No configuration found for package ${pkg.name}, downloaded a minimal YAML`,
128+
);
129+
await downloadPackageYAML(minimalYaml, pkg.name!);
130+
return;
131+
}
132+
await downloadPackageYAML(configYaml, pkg.name!);
133+
} catch (err: any) {
134+
const errorMessage =
135+
err?.message || err?.toString() || 'Unknown error occurred';
136+
onError?.(
137+
`Failed to download package ${pkg.name}: ${errorMessage}`,
138+
);
139+
}
115140
}}
116141
>
117142
<FileDownloadOutlinedIcon />
@@ -235,10 +260,12 @@ export const TogglePackage = ({
235260
pkg,
236261
isProductionEnv,
237262
isInstallationEnabled,
263+
onError,
238264
}: {
239265
pkg: InstalledPackageRow;
240266
isProductionEnv: boolean;
241267
isInstallationEnabled: boolean;
268+
onError?: (error: string) => void;
242269
}) => {
243270
const { t } = useTranslation();
244271
const { installedPackages, setInstalledPackages } = useInstallationContext();
@@ -323,17 +350,20 @@ export const TogglePackage = ({
323350
};
324351
setInstalledPackages(updated);
325352
} else {
326-
// eslint-disable-next-line no-console
327-
console.warn(
328-
`[Package Toggle] Package toggle responded with non-OK status:`,
329-
(res as any)?.error?.message ?? res,
353+
const errorMessage =
354+
(res as any)?.error?.message ?? res?.toString() ?? 'Unknown error';
355+
onError?.(
356+
`Failed to ${isPackageEnabled ? 'disable' : 'enable'} package ${pkg.name}: ${errorMessage}`,
330357
);
331358
}
332359
} catch (err: any) {
333-
// eslint-disable-next-line no-console
334-
console.error(
335-
`[Package Toggle] Failed to toggle package}:`,
336-
err?.error?.message ?? err,
360+
const errorMessage =
361+
err?.error?.message ??
362+
err?.message ??
363+
err?.toString() ??
364+
'Unknown error';
365+
onError?.(
366+
`Failed to ${isPackageEnabled ? 'disable' : 'enable'} package ${pkg.name}: ${errorMessage}`,
337367
);
338368
}
339369
};

workspaces/extensions/plugins/extensions/src/pages/ExtensionsPackageInstallPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const PackageEditHeader = () => {
3535

3636
const pkg = usePackage(params.namespace, params.name);
3737

38-
const displayName = pkg.data?.metadata.title ?? params.name;
38+
const displayName = pkg.data?.metadata?.title ?? params.name;
3939
const title =
4040
location?.state?.viewOnly || !pkg.data?.spec?.dynamicArtifact
4141
? displayName

0 commit comments

Comments
 (0)