From d8a33528fdebd85d21cc2e6b57d8a623cc9757e2 Mon Sep 17 00:00:00 2001 From: Edoardo Ranghieri Date: Sun, 8 Sep 2024 01:23:23 +0200 Subject: [PATCH] refactor: remove additional `fetchError` prop from hook return object This commit removes the `fetchError` prop from hook return object. Now the returned object is of type `SafeActionResult`. If an error gets thrown inside an action, and the `handleServerError` init option rethrows it, now the `execute`/`executeAsync` functions throw it inside the component, so the handling is up to the user. --- packages/next-safe-action/src/hooks-utils.ts | 10 +++---- packages/next-safe-action/src/hooks.ts | 31 ++++---------------- packages/next-safe-action/src/hooks.types.ts | 21 ++----------- 3 files changed, 13 insertions(+), 49 deletions(-) diff --git a/packages/next-safe-action/src/hooks-utils.ts b/packages/next-safe-action/src/hooks-utils.ts index 5fc3f5e..e4570af 100644 --- a/packages/next-safe-action/src/hooks-utils.ts +++ b/packages/next-safe-action/src/hooks-utils.ts @@ -2,7 +2,8 @@ import * as React from "react"; import {} from "react/experimental"; import type {} from "zod"; import type { InferIn, Schema } from "./adapters/types"; -import type { HookActionStatus, HookBaseUtils, HookCallbacks, HookResult, HookShorthandStatus } from "./hooks.types"; +import type { HookActionStatus, HookBaseUtils, HookCallbacks, HookShorthandStatus } from "./hooks.types"; +import type { SafeActionResult } from "./index.types"; export const getActionStatus = < ServerError, @@ -18,7 +19,7 @@ export const getActionStatus = < }: { isIdle: boolean; isExecuting: boolean; - result: HookResult; + result: SafeActionResult; }): HookActionStatus => { if (isIdle) { return "idle"; @@ -27,8 +28,7 @@ export const getActionStatus = < } else if ( typeof result.validationErrors !== "undefined" || typeof result.bindArgsValidationErrors !== "undefined" || - typeof result.serverError !== "undefined" || - typeof result.fetchError !== "undefined" + typeof result.serverError !== "undefined" ) { return "hasErrored"; } else { @@ -87,7 +87,7 @@ export const useActionCallbacks = < status, cb, }: { - result: HookResult; + result: SafeActionResult; input: S extends Schema ? InferIn : undefined; status: HookActionStatus; cb?: HookCallbacks; diff --git a/packages/next-safe-action/src/hooks.ts b/packages/next-safe-action/src/hooks.ts index ff7a630..b1c3ce6 100644 --- a/packages/next-safe-action/src/hooks.ts +++ b/packages/next-safe-action/src/hooks.ts @@ -1,7 +1,5 @@ "use client"; -import { isNotFoundError } from "next/dist/client/components/not-found.js"; -import { isRedirectError } from "next/dist/client/components/redirect.js"; import * as React from "react"; import {} from "react/experimental"; import type {} from "zod"; @@ -10,12 +8,11 @@ import { getActionShorthandStatusObject, getActionStatus, useActionCallbacks, us import type { HookBaseUtils, HookCallbacks, - HookResult, HookSafeActionFn, UseActionHookReturn, UseOptimisticActionHookReturn, } from "./hooks.types"; -import { isError } from "./utils"; +import type { SafeActionResult } from "./index.types"; // HOOKS @@ -38,7 +35,7 @@ export const useAction = < utils?: HookBaseUtils & HookCallbacks ): UseActionHookReturn => { const [isTransitioning, startTransition] = React.useTransition(); - const [result, setResult] = React.useState>({}); + const [result, setResult] = React.useState>({}); const [clientInput, setClientInput] = React.useState : void>(); const [isExecuting, setIsExecuting] = React.useState(false); const [isIdle, setIsIdle] = React.useState(true); @@ -57,11 +54,7 @@ export const useAction = < safeActionFn(input as S extends Schema ? InferIn : undefined) .then((res) => setResult(res ?? {})) .catch((e) => { - if (isRedirectError(e) || isNotFoundError(e)) { - throw e; - } - - setResult({ fetchError: isError(e) ? e.message : "Something went wrong" }); + throw e; }) .finally(() => { setIsExecuting(false); @@ -87,11 +80,6 @@ export const useAction = < resolve(res); }) .catch((e) => { - if (isRedirectError(e) || isNotFoundError(e)) { - throw e; - } - - setResult({ fetchError: isError(e) ? e.message : "Something went wrong" }); reject(e); }) .finally(() => { @@ -163,7 +151,7 @@ export const useOptimisticAction = < HookCallbacks ): UseOptimisticActionHookReturn => { const [isTransitioning, startTransition] = React.useTransition(); - const [result, setResult] = React.useState>({}); + const [result, setResult] = React.useState>({}); const [clientInput, setClientInput] = React.useState : void>(); const [isExecuting, setIsExecuting] = React.useState(false); const [isIdle, setIsIdle] = React.useState(true); @@ -187,11 +175,7 @@ export const useOptimisticAction = < safeActionFn(input as S extends Schema ? InferIn : undefined) .then((res) => setResult(res ?? {})) .catch((e) => { - if (isRedirectError(e) || isNotFoundError(e)) { - throw e; - } - - setResult({ fetchError: isError(e) ? e.message : "Something went wrong" }); + throw e; }) .finally(() => { setIsExecuting(false); @@ -218,11 +202,6 @@ export const useOptimisticAction = < resolve(res); }) .catch((e) => { - if (isRedirectError(e) || isNotFoundError(e)) { - throw e; - } - - setResult({ fetchError: isError(e) ? e.message : "Something went wrong" }); reject(e); }) .finally(() => { diff --git a/packages/next-safe-action/src/hooks.types.ts b/packages/next-safe-action/src/hooks.types.ts index 99a8a95..9a287e9 100644 --- a/packages/next-safe-action/src/hooks.types.ts +++ b/packages/next-safe-action/src/hooks.types.ts @@ -13,21 +13,6 @@ export type HookBaseUtils = { }) & { delayMs?: number }; }; -/** - * Type of `result` object returned by `useAction`, `useOptimisticAction` and `useStateAction` hooks. - * If a server-client communication error occurs, `fetchError` will be set to the error message. - */ -export type HookResult< - ServerError, - S extends Schema | undefined, - BAS extends readonly Schema[], - CVE, - CBAVE, - Data, -> = SafeActionResult & { - fetchError?: string; -}; - /** * Type of hooks callbacks. These are executed when action is in a specific state. */ @@ -42,11 +27,11 @@ export type HookCallbacks< onExecute?: (args: { input: S extends Schema ? InferIn : undefined }) => MaybePromise; onSuccess?: (args: { data?: Data; input: S extends Schema ? InferIn : undefined }) => MaybePromise; onError?: (args: { - error: Prettify, "data">>; + error: Prettify, "data">>; input: S extends Schema ? InferIn : undefined; }) => MaybePromise; onSettled?: (args: { - result: Prettify>; + result: Prettify>; input: S extends Schema ? InferIn : undefined; }) => MaybePromise; }; @@ -115,7 +100,7 @@ export type UseActionHookReturn< input: S extends Schema ? InferIn : void ) => Promise | undefined>; input: S extends Schema ? InferIn : undefined; - result: Prettify>; + result: Prettify>; reset: () => void; status: HookActionStatus; } & HookShorthandStatus;