diff --git a/interface/src/SignIn.tsx b/interface/src/SignIn.tsx index 602c44588..b5e4139b1 100644 --- a/interface/src/SignIn.tsx +++ b/interface/src/SignIn.tsx @@ -9,6 +9,8 @@ import * as AuthenticationApi from './api/authentication'; import { PROJECT_NAME } from './api/env'; import { AuthenticationContext } from './contexts/authentication'; +import { AxiosError } from 'axios'; + import { extractErrorMessage, onEnterCallback, updateValue } from './utils'; import { SignInRequest } from './types'; import { ValidatedTextField } from './components'; @@ -42,9 +44,11 @@ const SignIn: FC = () => { try { const { data: loginResponse } = await AuthenticationApi.signIn(signInRequest); authenticationContext.signIn(loginResponse.access_token); - } catch (error: any) { - if (error.response?.status === 401) { - enqueueSnackbar('Invalid login details', { variant: 'warning' }); + } catch (error: unknown) { + if (error instanceof AxiosError) { + if (error.response?.status === 401) { + enqueueSnackbar('Invalid login details', { variant: 'warning' }); + } } else { enqueueSnackbar(extractErrorMessage(error, 'Unexpected error, please try again'), { variant: 'error' }); } diff --git a/interface/src/components/upload/SingleUpload.tsx b/interface/src/components/upload/SingleUpload.tsx index d58cc890d..f1cb6fb18 100644 --- a/interface/src/components/upload/SingleUpload.tsx +++ b/interface/src/components/upload/SingleUpload.tsx @@ -24,13 +24,19 @@ const getBorderColor = (theme: Theme, props: DropzoneState) => { export interface SingleUploadProps { onDrop: (acceptedFiles: File[]) => void; onCancel: () => void; - accept?: string | string[]; uploading: boolean; progress?: ProgressEvent; } -const SingleUpload: FC = ({ onDrop, onCancel, accept, uploading, progress }) => { - const dropzoneState = useDropzone({ onDrop, accept, disabled: uploading, multiple: false }); +const SingleUpload: FC = ({ onDrop, onCancel, uploading, progress }) => { + const dropzoneState = useDropzone({ + onDrop, + accept: { + 'application/octet-stream': ['.bin'] + }, + disabled: uploading, + multiple: false + }); const { getRootProps, getInputProps } = dropzoneState; const theme = useTheme(); diff --git a/interface/src/components/upload/useFileUpload.ts b/interface/src/components/upload/useFileUpload.ts index d7d476900..b7529020f 100644 --- a/interface/src/components/upload/useFileUpload.ts +++ b/interface/src/components/upload/useFileUpload.ts @@ -43,7 +43,7 @@ const useFileUpload = ({ upload }: MediaUploadOptions) => { }); resetUploadingStates(); enqueueSnackbar('Upload successful', { variant: 'success' }); - } catch (error: any) { + } catch (error: unknown) { if (axios.isCancel(error)) { enqueueSnackbar('Upload aborted', { variant: 'warning' }); } else { diff --git a/interface/src/contexts/authentication/Authentication.tsx b/interface/src/contexts/authentication/Authentication.tsx index 93f09b77f..9577fbee4 100644 --- a/interface/src/contexts/authentication/Authentication.tsx +++ b/interface/src/contexts/authentication/Authentication.tsx @@ -23,9 +23,9 @@ const Authentication: FC = ({ children }) => { const decodedMe = AuthenticationApi.decodeMeJWT(accessToken); setMe(decodedMe); enqueueSnackbar(`Logged in as ${decodedMe.username}`, { variant: 'success' }); - } catch (error: any) { + } catch (error: unknown) { setMe(undefined); - throw new Error('Failed to parse JWT ' + error.message); + throw new Error('Failed to parse JWT'); } }; @@ -49,7 +49,7 @@ const Authentication: FC = ({ children }) => { await AuthenticationApi.verifyAuthorization(); setMe(AuthenticationApi.decodeMeJWT(accessToken)); setInitialized(true); - } catch (error: any) { + } catch (error: unknown) { setMe(undefined); setInitialized(true); } diff --git a/interface/src/contexts/features/FeaturesLoader.tsx b/interface/src/contexts/features/FeaturesLoader.tsx index e02c3411c..8f412717c 100644 --- a/interface/src/contexts/features/FeaturesLoader.tsx +++ b/interface/src/contexts/features/FeaturesLoader.tsx @@ -16,7 +16,7 @@ const FeaturesLoader: FC = (props) => { try { const response = await FeaturesApi.readFeatures(); setFeatures(response.data); - } catch (error: any) { + } catch (error: unknown) { setErrorMessage(extractErrorMessage(error, 'Failed to fetch application details.')); } }, []); diff --git a/interface/src/framework/network/WiFiNetworkScanner.tsx b/interface/src/framework/network/WiFiNetworkScanner.tsx index 9f3798f5f..169bc6951 100644 --- a/interface/src/framework/network/WiFiNetworkScanner.tsx +++ b/interface/src/framework/network/WiFiNetworkScanner.tsx @@ -1,13 +1,14 @@ import { useEffect, FC, useState, useCallback, useRef } from 'react'; import { useSnackbar } from 'notistack'; +import { AxiosError } from 'axios'; + import { Button } from '@mui/material'; import PermScanWifiIcon from '@mui/icons-material/PermScanWifi'; import * as NetworkApi from '../../api/network'; import { WiFiNetwork, WiFiNetworkList } from '../../types'; import { ButtonRow, FormLoader, SectionContent } from '../../components'; -import { extractErrorMessage } from '../../utils'; import WiFiNetworkSelector from './WiFiNetworkSelector'; @@ -52,8 +53,12 @@ const WiFiNetworkScanner: FC = () => { newNetworkList.networks.sort(compareNetworks); setNetworkList(newNetworkList); } - } catch (error: any) { - finishedWithError(extractErrorMessage(error, 'Problem listing WiFi networks')); + } catch (error: unknown) { + if (error instanceof AxiosError) { + finishedWithError('Problem listing WiFi networks ' + error.response?.data.message); + } else { + finishedWithError('Problem listing WiFi networks'); + } } }, [finishedWithError]); @@ -64,8 +69,12 @@ const WiFiNetworkScanner: FC = () => { try { await NetworkApi.scanNetworks(); setTimeout(pollNetworkList, POLLING_FREQUENCY); - } catch (error: any) { - finishedWithError(extractErrorMessage(error, 'Problem scanning for WiFi networks')); + } catch (error: unknown) { + if (error instanceof AxiosError) { + finishedWithError('Problem scanning for WiFi networks ' + error.response?.data.message); + } else { + finishedWithError('Problem scanning for WiFi networks'); + } } }, [finishedWithError, pollNetworkList]); diff --git a/interface/src/framework/ntp/NTPStatusForm.tsx b/interface/src/framework/ntp/NTPStatusForm.tsx index 2e0f03957..51182af5f 100644 --- a/interface/src/framework/ntp/NTPStatusForm.tsx +++ b/interface/src/framework/ntp/NTPStatusForm.tsx @@ -86,7 +86,7 @@ const NTPStatusForm: FC = () => { enqueueSnackbar('Time set', { variant: 'success' }); setSettingTime(false); loadData(); - } catch (error: any) { + } catch (error: unknown) { enqueueSnackbar(extractErrorMessage(error, 'Problem updating time'), { variant: 'error' }); } finally { setProcessing(false); diff --git a/interface/src/framework/security/GenerateToken.tsx b/interface/src/framework/security/GenerateToken.tsx index e834b9d26..75296c946 100644 --- a/interface/src/framework/security/GenerateToken.tsx +++ b/interface/src/framework/security/GenerateToken.tsx @@ -33,7 +33,7 @@ const GenerateToken: FC = ({ username, onClose }) => { const getToken = useCallback(async () => { try { setToken((await SecurityApi.generateToken(username)).data); - } catch (error: any) { + } catch (error: unknown) { enqueueSnackbar(extractErrorMessage(error, 'Problem generating token'), { variant: 'error' }); } }, [username, enqueueSnackbar]); diff --git a/interface/src/framework/system/FirmwareFileUpload.tsx b/interface/src/framework/system/FirmwareFileUpload.tsx index 8e5a056f3..a0b212fdf 100644 --- a/interface/src/framework/system/FirmwareFileUpload.tsx +++ b/interface/src/framework/system/FirmwareFileUpload.tsx @@ -21,7 +21,6 @@ const FirmwareFileUpload: FC = ({ uploadFirmware }) => { /> )} { try { await SystemApi.readSystemStatus(POLL_TIMEOUT); document.location.href = '/firmwareUpdated'; - } catch (error: any) { + } catch (error: unknown) { if (new Date().getTime() < timeoutAt.current) { setTimeoutId(setTimeout(poll.current, POLL_INTERVAL)); } else { diff --git a/interface/src/framework/system/SystemLog.tsx b/interface/src/framework/system/SystemLog.tsx index 7878691f8..9d5413aa6 100644 --- a/interface/src/framework/system/SystemLog.tsx +++ b/interface/src/framework/system/SystemLog.tsx @@ -106,7 +106,7 @@ const SystemLog: FC = () => { if (response.status !== 200) { enqueueSnackbar('Problem applying log settings', { variant: 'error' }); } - } catch (error: any) { + } catch (error: unknown) { enqueueSnackbar(extractErrorMessage(error, 'Problem applying log settings'), { variant: 'error' }); } } @@ -158,7 +158,7 @@ const SystemLog: FC = () => { const fetchLog = useCallback(async () => { try { setLogEntries((await SystemApi.readLogEntries()).data); - } catch (error: any) { + } catch (error: unknown) { setErrorMessage(extractErrorMessage(error, 'Failed to fetch log')); } }, []); diff --git a/interface/src/framework/system/SystemStatusForm.tsx b/interface/src/framework/system/SystemStatusForm.tsx index 092ca03ba..62c333fce 100644 --- a/interface/src/framework/system/SystemStatusForm.tsx +++ b/interface/src/framework/system/SystemStatusForm.tsx @@ -81,7 +81,7 @@ const SystemStatusForm: FC = () => { try { await SystemApi.restart(); enqueueSnackbar('EMS-ESP is restarting...', { variant: 'info' }); - } catch (error: any) { + } catch (error: unknown) { enqueueSnackbar(extractErrorMessage(error, 'Problem restarting device'), { variant: 'error' }); } finally { setConfirmRestart(false); @@ -179,7 +179,7 @@ const SystemStatusForm: FC = () => { try { await SystemApi.factoryReset(); enqueueSnackbar('Device has been factory reset and will now restart', { variant: 'info' }); - } catch (error: any) { + } catch (error: unknown) { enqueueSnackbar(extractErrorMessage(error, 'Problem factory resetting the device'), { variant: 'error' }); } finally { setConfirmFactoryReset(false); diff --git a/interface/src/project/HelpInformation.tsx b/interface/src/project/HelpInformation.tsx index 9790071e9..803f30b83 100644 --- a/interface/src/project/HelpInformation.tsx +++ b/interface/src/project/HelpInformation.tsx @@ -48,7 +48,7 @@ const HelpInformation: FC = () => { document.body.removeChild(a); enqueueSnackbar('File downloaded', { variant: 'info' }); } - } catch (error: any) { + } catch (error: unknown) { enqueueSnackbar(extractErrorMessage(error, 'Problem with downloading'), { variant: 'error' }); } }; diff --git a/interface/src/project/SettingsApplication.tsx b/interface/src/project/SettingsApplication.tsx index 2213634ac..0ea86722b 100644 --- a/interface/src/project/SettingsApplication.tsx +++ b/interface/src/project/SettingsApplication.tsx @@ -64,7 +64,7 @@ const SettingsApplication: FC = () => { eth_clock_mode: response.data.eth_clock_mode }); } - } catch (error: any) { + } catch (error: unknown) { enqueueSnackbar(extractErrorMessage(error, 'Problem fetching board profile'), { variant: 'error' }); } finally { setProcessingBoard(false); @@ -103,7 +103,7 @@ const SettingsApplication: FC = () => { try { await EMSESP.restart(); enqueueSnackbar('EMS-ESP is restarting...', { variant: 'info' }); - } catch (error: any) { + } catch (error: unknown) { enqueueSnackbar(extractErrorMessage(error, 'Problem restarting device'), { variant: 'error' }); } }; diff --git a/interface/src/utils/endpoints.ts b/interface/src/utils/endpoints.ts index 86265b0a5..24d88fe1e 100644 --- a/interface/src/utils/endpoints.ts +++ b/interface/src/utils/endpoints.ts @@ -1,4 +1,10 @@ import { AxiosError } from 'axios'; -export const extractErrorMessage = (error: AxiosError, defaultMessage: string) => - (error.response && error.response.data ? error.response.data.message : error.message) || defaultMessage; +export const extractErrorMessage = (error: unknown, defaultMessage: string) => { + if (error instanceof AxiosError) { + return error.response && error.response.data && error?.response?.data?.message; + } else if (error instanceof Error) { + return error.message; + } + return defaultMessage; +}; diff --git a/interface/src/utils/useRest.ts b/interface/src/utils/useRest.ts index ca948d0ec..e889e4521 100644 --- a/interface/src/utils/useRest.ts +++ b/interface/src/utils/useRest.ts @@ -22,7 +22,7 @@ export const useRest = ({ read, update }: RestRequestOptions) => { setErrorMessage(undefined); try { setData((await read()).data); - } catch (error: any) { + } catch (error: unknown) { const message = extractErrorMessage(error, 'Problem loading data'); enqueueSnackbar(message, { variant: 'error' }); setErrorMessage(message); @@ -45,7 +45,7 @@ export const useRest = ({ read, update }: RestRequestOptions) => { } else { enqueueSnackbar('Settings saved', { variant: 'success' }); } - } catch (error: any) { + } catch (error: unknown) { const message = extractErrorMessage(error, 'Problem saving data'); enqueueSnackbar(message, { variant: 'error' }); setErrorMessage(message);