diff --git a/apps/kyb-app/src/common/components/organisms/ErrorScreen/ErrorScreen.tsx b/apps/kyb-app/src/common/components/organisms/ErrorScreen/ErrorScreen.tsx index 11e62938f7..da804fdc73 100644 --- a/apps/kyb-app/src/common/components/organisms/ErrorScreen/ErrorScreen.tsx +++ b/apps/kyb-app/src/common/components/organisms/ErrorScreen/ErrorScreen.tsx @@ -1,9 +1,11 @@ import { AccessTokenIsMissingError } from '@/common/errors/access-token-is-missing'; import { InvalidAccessTokenError } from '@/common/errors/invalid-access-token'; +import { ServerNotAvailableError } from '@/common/errors/server-not-available'; import { useRouteError } from 'react-router-dom'; import { AppErrorScreen } from '../../molecules/AppErrorScreen'; import { InvalidAccessTokenErrorScreen } from './InvalidAccessToken'; import { MissingTokenErrorScreen } from './MissingTokenErrorScreen'; +import { ServerNotAvailableErrorScreen } from './ServerNotAvailable'; export const ErrorScreen = () => { const error = useRouteError(); @@ -16,6 +18,10 @@ export const ErrorScreen = () => { return ; } + if (error instanceof ServerNotAvailableError) { + return ; + } + return ( { + return ( + +

We are unable to connect to our servers at this time.

+

This could be due to maintenance or temporary technical difficulties.

+
    +
  • + 1. Please wait a few minutes and try refreshing the page +
  • +
  • + 2. Check your internet connection +
  • +
  • + 3. If the problem persists, our servers may be undergoing maintenance. Please + try again later or contact support +
  • +
+ + } + /> + ); +}; diff --git a/apps/kyb-app/src/common/errors/server-not-available.ts b/apps/kyb-app/src/common/errors/server-not-available.ts new file mode 100644 index 0000000000..2811770ebc --- /dev/null +++ b/apps/kyb-app/src/common/errors/server-not-available.ts @@ -0,0 +1,5 @@ +export class ServerNotAvailableError extends Error { + constructor() { + super('Server not available'); + } +} diff --git a/apps/kyb-app/src/common/providers/DependenciesProvider/DependenciesProvider.tsx b/apps/kyb-app/src/common/providers/DependenciesProvider/DependenciesProvider.tsx index 19a605ec14..54d7b65524 100644 --- a/apps/kyb-app/src/common/providers/DependenciesProvider/DependenciesProvider.tsx +++ b/apps/kyb-app/src/common/providers/DependenciesProvider/DependenciesProvider.tsx @@ -1,4 +1,5 @@ import { InvalidAccessTokenError } from '@/common/errors/invalid-access-token'; +import { ServerNotAvailableError } from '@/common/errors/server-not-available'; import { useCustomerQuery } from '@/hooks/useCustomerQuery'; import { useEndUserQuery } from '@/hooks/useEndUserQuery'; import { useFlowContextQuery } from '@/hooks/useFlowContextQuery'; @@ -59,6 +60,13 @@ export const DependenciesProvider: FunctionComponent if (!Array.isArray(errors) || !errors?.length) return; const handleErrors = async (errors: HTTPError[]) => { + // If there is no response, it means that the server is not available + if (errors.every(error => !error.response)) { + setError(new ServerNotAvailableError()); + + return; + } + const isShouldIgnore = await isShouldIgnoreErrors(errors); if (isShouldIgnore) return; diff --git a/apps/kyb-app/src/common/utils/request.ts b/apps/kyb-app/src/common/utils/request.ts index d487a14839..9aade92bcd 100644 --- a/apps/kyb-app/src/common/utils/request.ts +++ b/apps/kyb-app/src/common/utils/request.ts @@ -1,3 +1,4 @@ +import { ServerNotAvailableError } from '@/common/errors/server-not-available'; import { getAccessToken } from '@/helpers/get-access-token.helper'; import * as Sentry from '@sentry/react'; import ky, { HTTPError } from 'ky'; @@ -6,13 +7,26 @@ export const request = ky.create({ prefixUrl: import.meta.env.VITE_API_URL || `${window.location.origin}/api/v1/`, retry: { limit: 1, - statusCodes: [500, 408, 404, 404, 403, 401], + statusCodes: [500, 408, 404, 404, 403, 401, 0], methods: ['get'], }, timeout: 30_000, + fetch: (input, init) => { + return fetch(input, init).catch(error => { + if (!error?.response?.statusCode) { + throw new ServerNotAvailableError(); + } + + throw error; + }); + }, hooks: { beforeRequest: [ request => { + if (!navigator.onLine) { + throw new ServerNotAvailableError(); + } + request.headers.set('Authorization', `Bearer ${getAccessToken()}`); }, ], @@ -21,6 +35,11 @@ export const request = ky.create({ async (error: HTTPError) => { const { request, response } = error; + // Check if server is not available + if (!response || error.name === 'TimeoutError') { + throw new ServerNotAvailableError(); + } + let responseBody = ''; try { @@ -29,7 +48,7 @@ export const request = ky.create({ /* empty */ } - Sentry.withScope(function (scope) { + Sentry.withScope(scope => { // group errors together based on their request and response scope.setFingerprint([ request.method, diff --git a/apps/kyb-app/src/router.tsx b/apps/kyb-app/src/router.tsx index f337dbbb9c..7bcef4ae48 100644 --- a/apps/kyb-app/src/router.tsx +++ b/apps/kyb-app/src/router.tsx @@ -1,6 +1,5 @@ import { CollectionFlow } from '@/pages/CollectionFlow'; import * as Sentry from '@sentry/react'; -import { motion } from 'motion/react'; import React from 'react'; import { createBrowserRouter, @@ -46,20 +45,6 @@ export const router = sentryCreateBrowserRouter([ path: 'signup', Component: SignUpPage, }, - { - path: 'test', - Component: () => ( - - c60c740a-34ac-4b39-b67b-4e3868497a74 - - ), - }, - // TODO: 404 Page? ], }, ],