Skip to content

Commit

Permalink
feat: differentiate between connectivity and model errors
Browse files Browse the repository at this point in the history
  • Loading branch information
johangirod committed Jun 17, 2024
1 parent ac882f1 commit 2cc4b32
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ export default function SubServicesSection({
if (
isDataLoading(servicePublic) ||
hasAnyError(servicePublic) ||
servicePublic.subServicesId?.length === 0
!servicePublic.subServicesId ||
servicePublic.subServicesId.length === 0
) {
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion components/section/data-section/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function AsyncDataSectionClient<T>({
if (hasFetchError(data)) {
return (
<Section {...props}>
<DataFetchErrorExplanation />
<DataFetchErrorExplanation fetchErrorType={data} />
</Section>
);
}
Expand Down
36 changes: 31 additions & 5 deletions components/section/data-section/error.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
import { Error } from '#components-ui/alerts';
import { IDataFetchingState } from '#models/data-fetching';

export default function DataFetchErrorExplanation() {
export default function DataFetchErrorExplanation({
fetchErrorType,
}: {
fetchErrorType:
| IDataFetchingState.CONNECTIVITY_ERROR
| IDataFetchingState.MODEL_ERROR;
}) {
if (fetchErrorType === IDataFetchingState.CONNECTIVITY_ERROR) {
return (
<Error>
<strong>Erreur lors du chargement de la donnée</strong>
<p>
Votre navigateur a rencontré une erreur en essayant de charger cette
donnée. Cela peut arriver si vous avez une connexion internet
instable, si vous êtes sur un réseau public, ou derrière un VPN.
</p>
<p>
Vous pouvez essayer de recharger la page pour corriger le problème.
</p>
</Error>
);
}
return (
<Error>
<strong>Erreur lors du chargement de la donnée</strong>
<p>
Votre navigateur a rencontré une erreur en essayant de charger cette
donnée. Cela peut arriver si vous avez une connexion internet instable
ou si vous utilisez un bloqueur de publicité.
Une erreur est survenue lors de la récupération de la donnée. Cela vient
probablement d’un problème technique de notre côté. Pas d’inquiétude, le
reste du site fonctionne toujours !
</p>

<p>
Ce problème a été automatiquement signalé à notre équipe technique, qui
va essayer de le corriger au plus vite.
</p>
<p>Vous pouvez essayer de recharger la page ou de revenir plus tard.</p>
<p className="fr-text--sm">
Si la situation perdure, merci de{' '}
<a href="https://www.data.gouv.fr/fr/faq/#contact">nous contacter</a>{' '}
Expand Down
37 changes: 22 additions & 15 deletions hooks/fetch/use-API-route-data.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useEffect, useState } from 'react';
import { IDataFetchingState } from '#models/data-fetching';
import { InternalError } from '#models/exceptions';
import { hasRights } from '#models/user/rights';
import { ISession } from '#models/user/session';
import { httpGet } from '#utils/network';
import {
FailToFetchError,
RequestAbortedDuringUnloadException,
} from '#utils/network/frontend';
import logErrorInSentry from '#utils/sentry';
import logErrorInSentry, { logWarningInSentry } from '#utils/sentry';
import { APIPath, RouteResponse } from 'app/api/data-fetching/routes-handlers';
import { APIRoutesScopes } from 'app/api/data-fetching/routes-scopes';

Expand Down Expand Up @@ -39,26 +40,32 @@ export function useAPIRouteData<T extends APIPath>(
'/api/data-fetching/' + route + '/' + slug
)
);
} catch (e: any) {
} catch (e: unknown) {
if (e instanceof RequestAbortedDuringUnloadException) {
return;
}
if (!e.status) {
setResponse(IDataFetchingState.ERROR);
// Errors that are not already logged server side
logErrorInSentry(
new FailToFetchError({
context: {
slug: slug,
page: '/api/data-fetching/' + route,
},
cause: e,
})
);
if (e instanceof FailToFetchError) {
e.context.slug = slug;
e.context.page = '/api/data-fetching/' + route;
if (!e.status || [408, 504, 429].includes(e.status)) {
logWarningInSentry(e);
setResponse(IDataFetchingState.CONNECTIVITY_ERROR);
return;
}
logErrorInSentry(e);
setResponse(IDataFetchingState.MODEL_ERROR);
return;
}
throw e;
logErrorInSentry(
new InternalError({
cause: e,
message: "Ce type d'erreur n'est pas géré",
})
);
setResponse(IDataFetchingState.MODEL_ERROR);
}
};

fetchAndTreatResponse();
}, [slug, route, session]);
return response;
Expand Down
18 changes: 14 additions & 4 deletions models/data-fetching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import {

export enum IDataFetchingState {
LOADING = '__DATAFETCHINGSTATE__LOADING__',
/** Error that occurs client-side */
UNAUTHORIZED = '__DATAFETCHINGSTATE__UNAUTHORIZED__',
ERROR = '__DATAFETCHINGSTATE__ERROR__',
/** Error that occurs client-side */
CONNECTIVITY_ERROR = '__DATAFETCHINGSTATE__CONNECTIVITY_ERROR__',
/** Error that occurs server-side */
MODEL_ERROR = '__DATAFETCHINGSTATE__MODEL_ERROR__',
}

export function isDataLoading<T>(
Expand All @@ -17,8 +21,13 @@ export function isDataLoading<T>(

export function hasFetchError<T>(
toBeDetermined: T | IDataFetchingState
): toBeDetermined is IDataFetchingState.ERROR {
return toBeDetermined === IDataFetchingState.ERROR;
): toBeDetermined is
| IDataFetchingState.CONNECTIVITY_ERROR
| IDataFetchingState.MODEL_ERROR {
return (
toBeDetermined === IDataFetchingState.CONNECTIVITY_ERROR ||
toBeDetermined === IDataFetchingState.MODEL_ERROR
);
}

export function isUnauthorized<T>(
Expand All @@ -30,7 +39,8 @@ export function isUnauthorized<T>(
export function hasAnyError<T>(
toBeDetermined: T | IDataFetchingState | IAPINotRespondingError
): toBeDetermined is
| IDataFetchingState.ERROR
| IDataFetchingState.CONNECTIVITY_ERROR
| IDataFetchingState.MODEL_ERROR
| IAPINotRespondingError
| IDataFetchingState.UNAUTHORIZED {
return (
Expand Down
2 changes: 1 addition & 1 deletion utils/network/frontend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export class RequestAbortedDuringUnloadException extends Exception {
export class FailToFetchError extends Exception {
constructor(
args: { context: IExceptionContext; cause: any },
public status = 500
public status: number
) {
super({
name: 'FailToFetchError',
Expand Down

0 comments on commit 2cc4b32

Please sign in to comment.