From 6d5fee823e4e797b905347e588fe6f5dac0ab297 Mon Sep 17 00:00:00 2001 From: Rafi Arrafif Date: Sat, 13 Sep 2025 12:50:43 +0700 Subject: [PATCH] :ok_hand: (review) update connector error handling Improve error handling by creating a function handler for connections on servers that use KY, and use the status key in the response as the key to success instead of catch. Use catch if an error occurs between the client and server, not between the server and backend. --- features/auth/lib/getOauthProviderList.ts | 2 +- features/auth/lib/requestOauthUrl.ts | 2 +- .../lib/sendCallbackToServer.ts | 25 +++++++++++++++--- features/oauth-callback/ui/LoadingProcess.tsx | 25 +++++++++++++++--- shared/{lib => helper}/backendApi.ts | 0 shared/{lib => helper}/delayButtonClick.ts | 0 shared/{api => lib/ky}/connector.ts | 0 shared/lib/ky/errorHandler.ts | 26 +++++++++++++++++++ 8 files changed, 71 insertions(+), 9 deletions(-) rename shared/{lib => helper}/backendApi.ts (100%) rename shared/{lib => helper}/delayButtonClick.ts (100%) rename shared/{api => lib/ky}/connector.ts (100%) create mode 100644 shared/lib/ky/errorHandler.ts diff --git a/features/auth/lib/getOauthProviderList.ts b/features/auth/lib/getOauthProviderList.ts index 40d8b9a..9dfdef1 100644 --- a/features/auth/lib/getOauthProviderList.ts +++ b/features/auth/lib/getOauthProviderList.ts @@ -1,5 +1,5 @@ "use server"; -import { api } from "@/shared/api/connector"; +import { api } from "@/shared/lib/ky/connector"; const getOauthProviderList = async () => { try { diff --git a/features/auth/lib/requestOauthUrl.ts b/features/auth/lib/requestOauthUrl.ts index 68947c2..0b38398 100644 --- a/features/auth/lib/requestOauthUrl.ts +++ b/features/auth/lib/requestOauthUrl.ts @@ -1,6 +1,6 @@ "use server"; -import { api } from "@/shared/api/connector"; +import { api } from "@/shared/lib/ky/connector"; import { redirect } from "next/navigation"; import { ResponseRequestOauthUrl } from "../types/responseRequestOauthUrl"; diff --git a/features/oauth-callback/lib/sendCallbackToServer.ts b/features/oauth-callback/lib/sendCallbackToServer.ts index 542cbfb..c726260 100644 --- a/features/oauth-callback/lib/sendCallbackToServer.ts +++ b/features/oauth-callback/lib/sendCallbackToServer.ts @@ -1,5 +1,14 @@ "use server"; -import { api } from "@/shared/api/connector"; +import { api } from "@/shared/lib/ky/connector"; +import { apiErrorHandler } from "@/shared/lib/ky/errorHandler"; +import { HTTPError } from "ky"; + +interface SendCallbackResponse { + success: boolean; + status: number; + text: { message: string }; + data?: any; +} /** * @function SendCallbackToServer @@ -52,7 +61,10 @@ import { api } from "@/shared/api/connector"; * - The callback URI is automatically constructed using the APP_DOMAIN environment variable. * - Ensure APP_DOMAIN is properly configured in your environment variables. */ -export const SendCallbackToServer = async (data: string, provider: string) => { +export const SendCallbackToServer = async ( + data: string, + provider: string +): Promise => { // Construct the backend and frontend handler URLs const backendHandlerUrl = `auth/${provider}/callback/`; const frontendHandlerUrl = `${process.env @@ -66,8 +78,13 @@ export const SendCallbackToServer = async (data: string, provider: string) => { // Parse the JSON response from the backend and return the result const result = await response.json(); - return result; + return { + success: true, + status: response.status, + text: { message: "Callback processed successfully" }, + data: result, + }; } catch (error) { - throw error; + return apiErrorHandler(error); } }; diff --git a/features/oauth-callback/ui/LoadingProcess.tsx b/features/oauth-callback/ui/LoadingProcess.tsx index e5a7a7c..fbb3667 100644 --- a/features/oauth-callback/ui/LoadingProcess.tsx +++ b/features/oauth-callback/ui/LoadingProcess.tsx @@ -14,15 +14,34 @@ const LoadingProcess = () => { // Forward the callback response to the backend server useRunOnce("forwardCallbackResponseToBackend", async () => { try { - await SendCallbackToServer( + const response = await SendCallbackToServer( window.location.search, params.provider as string ); - window.close(); + + if (response.success) { + window.close(); + } else { + addToast({ + title: "😬 Oops, there's a problem!", + description: response.text.message, + color: "danger", + timeout: 0, + endContent: ( + + ), + }); + } } catch (error) { console.log(error); addToast({ - title: "Oops, lost connection!", + title: "😵‍💫 Oops, lost connection!", description: "Check your internet and try again", color: "danger", timeout: 0, diff --git a/shared/lib/backendApi.ts b/shared/helper/backendApi.ts similarity index 100% rename from shared/lib/backendApi.ts rename to shared/helper/backendApi.ts diff --git a/shared/lib/delayButtonClick.ts b/shared/helper/delayButtonClick.ts similarity index 100% rename from shared/lib/delayButtonClick.ts rename to shared/helper/delayButtonClick.ts diff --git a/shared/api/connector.ts b/shared/lib/ky/connector.ts similarity index 100% rename from shared/api/connector.ts rename to shared/lib/ky/connector.ts diff --git a/shared/lib/ky/errorHandler.ts b/shared/lib/ky/errorHandler.ts new file mode 100644 index 0000000..d8b09b5 --- /dev/null +++ b/shared/lib/ky/errorHandler.ts @@ -0,0 +1,26 @@ +"use server"; + +import { HTTPError } from "ky"; + +export const apiErrorHandler = async ( + error: unknown, + safeFail: boolean = false +) => { + if (error instanceof HTTPError) { + return { + success: false, + status: error.response.status, + text: await error.response.json(), + }; + } + + if (safeFail) { + return { + success: false, + status: 500, + text: { message: "An unexpected error occurred" }, + }; + } else { + throw error; + } +};