diff --git a/apps/admin-x-framework/src/hooks/useHandleError.ts b/apps/admin-x-framework/src/hooks/useHandleError.ts index e041fe4694..9e5e8d88a9 100644 --- a/apps/admin-x-framework/src/hooks/useHandleError.ts +++ b/apps/admin-x-framework/src/hooks/useHandleError.ts @@ -3,7 +3,7 @@ import {showToast} from '@tryghost/admin-x-design-system'; import {useCallback} from 'react'; import toast from 'react-hot-toast'; import {useFramework} from '../providers/FrameworkProvider'; -import {APIError, JSONError, ValidationError} from '../utils/errors'; +import {APIError, ValidationError} from '../utils/errors'; /** * Generic error handling for API calls. This is enabled by default for queries (can be disabled by @@ -20,8 +20,7 @@ const useHandleError = () => { * so this toast is intended as a worst-case fallback message when we don't know what else to do. * */ - type HandleErrorReturnType = void | any; // eslint-disable-line @typescript-eslint/no-explicit-any - const handleError = useCallback((error: unknown, {withToast = true}: {withToast?: boolean} = {}) : HandleErrorReturnType => { + const handleError = useCallback((error: unknown, {withToast = true}: {withToast?: boolean} = {}) => { // eslint-disable-next-line no-console console.error(error); @@ -41,10 +40,6 @@ const useHandleError = () => { toast.remove(); - if (error instanceof JSONError && error.response?.status === 422) { - return error.data; - } - if (error instanceof APIError && error.response?.status === 418) { // We use this status in tests to indicate the API request was not mocked - // don't show a toast because it may block clicking things in the test diff --git a/apps/admin-x-settings/src/components/settings/site/ThemeModal.tsx b/apps/admin-x-settings/src/components/settings/site/ThemeModal.tsx index dbf034933f..f6b4b77e95 100644 --- a/apps/admin-x-settings/src/components/settings/site/ThemeModal.tsx +++ b/apps/admin-x-settings/src/components/settings/site/ThemeModal.tsx @@ -1,13 +1,14 @@ import AdvancedThemeSettings from './theme/AdvancedThemeSettings'; -import InvalidThemeModal from './theme/InvalidThemeModal'; +import InvalidThemeModal, {FatalErrors} from './theme/InvalidThemeModal'; import NiceModal, {NiceModalHandler, useModal} from '@ebay/nice-modal-react'; import OfficialThemes from './theme/OfficialThemes'; -import React, {useEffect, useRef, useState} from 'react'; +import React, {useEffect, useState} from 'react'; import ThemeInstalledModal from './theme/ThemeInstalledModal'; import ThemePreview from './theme/ThemePreview'; import {Breadcrumbs, Button, ConfirmationModal, FileUpload, LimitModal, Modal, PageHeader, TabView, showToast} from '@tryghost/admin-x-design-system'; import {HostLimitError, useLimiter} from '../../../hooks/useLimiter'; import {InstalledTheme, Theme, ThemesInstallResponseType, isDefaultOrLegacyTheme, useActivateTheme, useBrowseThemes, useInstallTheme, useUploadTheme} from '@tryghost/admin-x-framework/api/themes'; +import {JSONError} from '@tryghost/admin-x-framework/errors'; import {OfficialTheme} from '../../providers/SettingsAppProvider'; import {useHandleError} from '@tryghost/admin-x-framework/hooks'; import {useRouting} from '@tryghost/admin-x-framework/routing'; @@ -61,14 +62,6 @@ const ThemeToolbar: React.FC = ({ const [isUploading, setUploading] = useState(false); - const fileInputRef = useRef(null); - - const handleRetry = () => { - if (fileInputRef?.current) { - fileInputRef.current.click(); - } - }; - useEffect(() => { if (limiter) { // Sending a bad string to make sure it fails (empty string isn't valid) @@ -132,7 +125,7 @@ const ThemeToolbar: React.FC = ({ onActivate?: () => void }) => { let data: ThemesInstallResponseType | undefined; - let fatalErrors = null; + let fatalErrors: FatalErrors | null = null; try { setUploading(true); @@ -140,9 +133,11 @@ const ThemeToolbar: React.FC = ({ setUploading(false); } catch (e) { setUploading(false); - const errorsJson = await handleError(e) as {errors?: []}; - if (errorsJson?.errors) { - fatalErrors = errorsJson.errors; + + if (e instanceof JSONError && e.response?.status === 422 && e.data?.errors) { + fatalErrors = (e.data.errors as any) as FatalErrors; + } else { + handleError(e); } } @@ -155,7 +150,7 @@ const ThemeToolbar: React.FC = ({ fatalErrors, onRetry: async (modal) => { modal?.remove(); - handleRetry(); + handleUpload(); } }); } diff --git a/apps/admin-x-settings/src/components/settings/site/theme/InvalidThemeModal.tsx b/apps/admin-x-settings/src/components/settings/site/theme/InvalidThemeModal.tsx index 1a52a35c95..8a7b7d7ba9 100644 --- a/apps/admin-x-settings/src/components/settings/site/theme/InvalidThemeModal.tsx +++ b/apps/admin-x-settings/src/components/settings/site/theme/InvalidThemeModal.tsx @@ -9,7 +9,7 @@ type FatalError = { }; }; -type FatalErrors = FatalError[]; +export type FatalErrors = FatalError[]; export const ThemeProblemView = ({problem}:{problem: ThemeProblem}) => { const [isExpanded, setExpanded] = useState(false); @@ -63,8 +63,7 @@ const InvalidThemeModal: React.FC<{ if (fatalErrors) { warningPrompt =
- {fatalErrors?.map((error: any) => error?.details?.errors?.map((err: any) => - ))} + {fatalErrors?.map(error => error?.details?.errors?.map(err => ))}
; }