Implement useGuardedMutation hook for enhanced error handling in MachineContainer and update related components

master^2
Tudor Stanciu 2024-11-16 14:11:32 +02:00
parent 181c565b3c
commit feb2ab11f9
6 changed files with 50 additions and 11 deletions

View File

@ -14,7 +14,7 @@ import {
RestartMachine, RestartMachine,
ShutdownMachine ShutdownMachine
} from "types"; } from "types";
import { Key, NetworkError, mutationFetcher, useSWRMutation } from "units/swr"; import { Key, NetworkError, mutationFetcher, useGuardedMutation } from "units/swr";
import { usePingTrigger } from "../hooks"; import { usePingTrigger } from "../hooks";
type Props = { type Props = {
@ -48,20 +48,18 @@ const MachineContainer: React.FC<Props> = ({ machine, viewMode }) => {
onSuccess: manageActionResponse onSuccess: manageActionResponse
}); });
const { trigger: shutdownMachineTrigger } = useSWRMutation<MachineShutdown, NetworkError, Key, ShutdownMachine>( const { trigger: shutdownMachineTrigger } = useGuardedMutation<MachineShutdown, NetworkError, Key, ShutdownMachine>(
endpoints.network.machine.shutdown, endpoints.network.machine.shutdown,
mutationFetcher<ShutdownMachine>, mutationFetcher<ShutdownMachine>,
{ {
onError: err => blip.error(err.message),
onSuccess: manageActionResponse onSuccess: manageActionResponse
} }
); );
const { trigger: restartMachineTrigger } = useSWRMutation<MachineRestarted, NetworkError, Key, RestartMachine>( const { trigger: restartMachineTrigger } = useGuardedMutation<MachineRestarted, NetworkError, Key, RestartMachine>(
endpoints.network.machine.restart, endpoints.network.machine.restart,
mutationFetcher<RestartMachine>, mutationFetcher<RestartMachine>,
{ {
onError: err => blip.error(err.serverError.message || err.message),
onSuccess: manageActionResponse onSuccess: manageActionResponse
} }
); );

View File

@ -17,7 +17,8 @@ const usePingTrigger = (options: PingTriggerOptions) => {
mutationFetcher<PingMachine>, mutationFetcher<PingMachine>,
{ {
onError, onError,
onSuccess onSuccess,
throwOnError: false
} }
); );
return { pingMachineTrigger }; return { pingMachineTrigger };

View File

@ -3,18 +3,15 @@ import CacheSettingsComponent from "./CacheSettingsComponent";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { endpoints } from "utils/api"; import { endpoints } from "utils/api";
import { blip } from "utils"; import { blip } from "utils";
import { useSWRMutation, mutationFetcher, Key, NetworkError } from "units/swr"; import { useGuardedMutation, mutationFetcher, Key, NetworkError } from "units/swr";
const CacheSettingsContainer: React.FC = () => { const CacheSettingsContainer: React.FC = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { trigger } = useSWRMutation<void, NetworkError, Key, void>( const { trigger } = useGuardedMutation<void, NetworkError, Key, void>(
endpoints.system.resetCache, endpoints.system.resetCache,
mutationFetcher<void>, mutationFetcher<void>,
{ {
onError: err => {
blip.error(err.message);
},
onSuccess: () => blip.info(t("Settings.Cache.ResetInfo")) onSuccess: () => blip.info(t("Settings.Cache.ResetInfo"))
} }
); );

View File

@ -0,0 +1,3 @@
import useGuardedMutation from "./useGuardedMutation";
export { useGuardedMutation };

View File

@ -0,0 +1,39 @@
import useSWRMutation, { MutationFetcher, SWRMutationConfiguration, SWRMutationResponse } from "swr/mutation";
import { Key, NetworkError } from "../../swr";
import { blip } from "utils";
import { useMemo } from "react";
const defaultErrorHandler = (error: Error) => {
const isNetworkError = error instanceof NetworkError;
if (isNetworkError) {
blip.error(error.serverError.message || error.message);
return;
}
blip.error(error.message);
};
function useGuardedMutation<
Data = any,
Error = any,
SWRMutationKey extends Key = Key,
ExtraArg = never,
SWRData = Data
>(
key: SWRMutationKey,
fetcher: MutationFetcher<Data, SWRMutationKey, ExtraArg>,
options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & { throwOnError?: boolean }
): SWRMutationResponse<Data, Error, SWRMutationKey, ExtraArg> {
const opts = useMemo(
() =>
({
...options,
onError: options?.onError ?? defaultErrorHandler,
throwOnError: options?.throwOnError ?? false
} as SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData>),
[options]
);
return useSWRMutation<Data, Error, SWRMutationKey, ExtraArg, SWRData>(key, fetcher, opts);
}
export default useGuardedMutation;

View File

@ -4,6 +4,7 @@ import useSWRMutation from "swr/mutation";
export * from "./fetchers"; export * from "./fetchers";
export * from "./errors"; export * from "./errors";
export * from "./hooks";
export { useSWR, useSWRMutation }; export { useSWR, useSWRMutation };
export type { Key }; export type { Key };