Skip to content

Commit

Permalink
feat: added handling of network errors & network error page
Browse files Browse the repository at this point in the history
  • Loading branch information
chesterkmr committed Nov 20, 2024
1 parent 3ef32d2 commit f917e6b
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -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();
Expand All @@ -16,6 +18,10 @@ export const ErrorScreen = () => {
return <InvalidAccessTokenErrorScreen />;
}

if (error instanceof ServerNotAvailableError) {
return <ServerNotAvailableErrorScreen />;
}

return (
<AppErrorScreen
title="Something went wrong"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { AppErrorScreen } from '../../molecules/AppErrorScreen';

export const ServerNotAvailableErrorScreen = () => {
return (
<AppErrorScreen
title="Server Not Available"
description={
<div className="!text-muted-foreground flex flex-col gap-1">
<p>We are unable to connect to our servers at this time.</p>
<p>This could be due to maintenance or temporary technical difficulties.</p>
<ul>
<li>
<b>1.</b> Please wait a few minutes and try refreshing the page
</li>
<li>
<b>2.</b> Check your internet connection
</li>
<li>
<b>3.</b> If the problem persists, our servers may be undergoing maintenance. Please
try again later or contact support
</li>
</ul>
</div>
}
/>
);
};
5 changes: 5 additions & 0 deletions apps/kyb-app/src/common/errors/server-not-available.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export class ServerNotAvailableError extends Error {
constructor() {
super('Server not available');
}
}
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -59,6 +60,13 @@ export const DependenciesProvider: FunctionComponent<IDependenciesProviderProps>
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;
Expand Down
23 changes: 21 additions & 2 deletions apps/kyb-app/src/common/utils/request.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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()}`);
},
],
Expand All @@ -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 {
Expand All @@ -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,
Expand Down
15 changes: 0 additions & 15 deletions apps/kyb-app/src/router.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -46,20 +45,6 @@ export const router = sentryCreateBrowserRouter([
path: 'signup',
Component: SignUpPage,
},
{
path: 'test',
Component: () => (
<motion.div
initial={{ x: '100%', opacity: 1 }}
animate={{ x: 0, opacity: 1 }}
transition={{ duration: 0.7 }}
style={{ width: '100%', height: '100vh', backgroundColor: 'lightblue' }}
>
c60c740a-34ac-4b39-b67b-4e3868497a74
</motion.div>
),
},
// TODO: 404 Page?
],
},
],
Expand Down

0 comments on commit f917e6b

Please sign in to comment.