{season}
diff --git a/src/atoms/fetchCalls.tsx b/src/atoms/fetchCalls.tsx
index c2fb351..d5fb129 100644
--- a/src/atoms/fetchCalls.tsx
+++ b/src/atoms/fetchCalls.tsx
@@ -18,6 +18,7 @@ import {
nextEventTimeAtom,
} from './nextEvent';
import { raceAtom, seasonRacesAtom } from './races';
+import { serverErrorAtom } from './results';
import { allSeasonsAtom, seasonAtom } from './seasons';
import { allSessionsAtom, sessionAtom } from './sessions';
import { constructorStandingsAtom, driverStandingsAtom } from './standings';
@@ -50,12 +51,22 @@ export const fetchSchedule = atomEffect(
set(seasonRacesAtom, null);
const params = get(seasonAtom) && `?year=${get(seasonAtom)}`;
- fetchAPI('schedule' + params).then((data) => {
- set(seasonRacesAtom, data.EventSchedule);
+ fetchAPI('schedule' + params).then(
+ (res: DataConfigSchema['schedule'] | ServerErrorResponse) => {
+ const schedule = res as DataConfigSchema['schedule'];
- // Sync default year with server
- set(seasonAtom, data.year);
- });
+ const error = res as ServerErrorResponse;
+ if (error.detail) {
+ set(serverErrorAtom, error.detail[0].msg);
+ return;
+ }
+
+ set(seasonRacesAtom, schedule.EventSchedule);
+
+ // Sync default year with server
+ set(seasonAtom, schedule.year);
+ },
+ );
},
// Dependencies:
// seasonAtom
@@ -87,7 +98,14 @@ export const fetchSessionResults = atomEffect((get, set) => {
url += `?session=${sessionRound}`;
}
- fetchAPI(url).then((drivers: DriverResult[]) => {
+ fetchAPI(url).then((res: DriverResult[] | ServerErrorResponse) => {
+ const drivers = res as DriverResult[];
+
+ const error = res as ServerErrorResponse;
+ if (error.detail) {
+ set(serverErrorAtom, error.detail[0].msg);
+ return;
+ }
// Formulate Constructors
const constructors = formatConstructorResults(drivers);
@@ -115,12 +133,21 @@ export const fetchStandings = atomEffect((get, set) => {
const round = race === 'All Races' ? '' : `&round=${race.RoundNumber}`;
// Fetch
- fetchAPI('standings' + year + round).then(
- ({
- DriverStandings,
- ConstructorStandings,
- }: DataConfigSchema['standings']) => {
+ fetchAPI('standings' + year + round)
+ .then((res: DataConfigSchema['standings'] | ServerErrorResponse) => {
+ const { DriverStandings, ConstructorStandings } =
+ res as DataConfigSchema['standings'];
+
+ const error = res as ServerErrorResponse;
+ if (error.detail) {
+ set(serverErrorAtom, error.detail[0].msg);
+
+ // setDefault('standings')
+ return;
+ }
+
// Include Drivers in Constructors Info
+
const constructors = ConstructorStandings.map((cs) => {
const { name } = cs.Constructor;
return {
@@ -134,8 +161,8 @@ export const fetchStandings = atomEffect((get, set) => {
// Update standings
set(constructorStandingsAtom, constructors);
set(driverStandingsAtom, DriverStandings);
- },
- );
+ })
+ .catch((err) => err);
// dependencies
// seasonAtom
@@ -147,22 +174,30 @@ export const fetchNextEvent = atomEffect(
(get, set) => {
// Next event do not change, only fetch if null
if (!get(nextEventAtom)) {
- fetchAPI('next-event').then((data: ScheduleSchema) => {
- // Get session times
- const now = Date.now();
- const nextEvent = formatNextEvent(data);
-
- if (nextEvent === 'No session') return;
-
- set(nextEventAtom, nextEvent);
-
- if (nextEvent.time < now) {
- set(nextEventLiveAtom, true);
- set(nextEventTimeAtom, now - nextEvent.endTime);
- } else {
- set(nextEventTimeAtom, nextEvent.time - now);
- }
- });
+ fetchAPI('next-event').then(
+ (res: ScheduleSchema | ServerErrorResponse) => {
+ const data = res as ScheduleSchema;
+ const error = res as ServerErrorResponse;
+ if (error.detail) {
+ set(serverErrorAtom, error.detail[0].msg);
+ return;
+ }
+ // Get session times
+ const now = Date.now();
+ const nextEvent = formatNextEvent(data);
+
+ if (nextEvent === 'No session') return;
+
+ set(nextEventAtom, nextEvent);
+
+ if (nextEvent.time < now) {
+ set(nextEventLiveAtom, true);
+ set(nextEventTimeAtom, now - nextEvent.endTime);
+ } else {
+ set(nextEventTimeAtom, nextEvent.time - now);
+ }
+ },
+ );
}
},
// Dependencies: nextEventAtom
diff --git a/src/atoms/results.tsx b/src/atoms/results.tsx
index eac3103..7e24066 100644
--- a/src/atoms/results.tsx
+++ b/src/atoms/results.tsx
@@ -15,6 +15,9 @@ import { raceAtom, seasonRacesAtom } from './races';
import { seasonAtom } from './seasons';
import { allSessionsAtom, sessionAtom } from './sessions';
+// Server Error Atom
+export const serverErrorAtom = atom('');
+
// Telemetry Active
export const telemetryDisableAtom = atom(true);
// Telemetry is disabled if no race and driver are selected
diff --git a/src/results.d.ts b/src/results.d.ts
index 0699074..ef5927d 100644
--- a/src/results.d.ts
+++ b/src/results.d.ts
@@ -94,7 +94,10 @@ interface ConstructorResult {
// UI format
interface DataConfigSchema {
seasons: string[];
- schedule: ScheduleSchema[];
+ schedule: {
+ year: string;
+ EventSchedule: ScheduleSchema[];
+ };
drivers: string[];
sessions: string[];
standings: {
@@ -109,6 +112,16 @@ interface DataConfigSchema {
};
}
+interface ServerErrorResponse {
+ detail: [
+ {
+ loc: string[];
+ msg: string;
+ input: string;
+ },
+ ];
+}
+
// UI Format Next Event
interface NextEventProps {
name: string;
diff --git a/src/utils/fakerData.tsx b/src/utils/fakerData.tsx
index 657c35a..ac6b36e 100644
--- a/src/utils/fakerData.tsx
+++ b/src/utils/fakerData.tsx
@@ -41,31 +41,34 @@ const driverResults: DriverResult[] = Array.from(Array(10).keys()).map(() => ({
export const dataConfig: DataConfigSchema = {
seasons: f1Seasons(),
- schedule: Array.from(Array(3).keys()).map(() => ({
- RoundNumber: 0,
- Country: faker.location.country(),
- Location: faker.location.city(),
- OfficialEventName: faker.word.words(5),
- EventDate: faker.date.future({ years: 1 }).toString(),
- EventName: faker.word.words(3),
- EventFormat: 'string',
- Session1: 'string',
- Session1Date: faker.date.future({ years: 1 }).toString(),
- Session1DateUtc: faker.date.future({ years: 1 }).toString(),
- Session2: 'string',
- Session2Date: faker.date.future({ years: 1 }).toString(),
- Session2DateUtc: faker.date.future({ years: 1 }).toString(),
- Session3: 'string',
- Session3Date: faker.date.future({ years: 1 }).toString(),
- Session3DateUtc: faker.date.future({ years: 1 }).toString(),
- Session4: 'string',
- Session4Date: faker.date.future({ years: 1 }).toString(),
- Session4DateUtc: faker.date.future({ years: 1 }).toString(),
- Session5: 'string',
- Session5Date: faker.date.future({ years: 1 }).toString(),
- Session5DateUtc: faker.date.future({ years: 1 }).toString(),
- F1ApiSupport: true,
- })),
+ schedule: {
+ year: faker.number.int({ min: 1950, max: 2024 }).toString(),
+ EventSchedule: Array.from(Array(3).keys()).map(() => ({
+ RoundNumber: 0,
+ Country: faker.location.country(),
+ Location: faker.location.city(),
+ OfficialEventName: faker.word.words(5),
+ EventDate: faker.date.future({ years: 1 }).toString(),
+ EventName: faker.word.words(3),
+ EventFormat: 'string',
+ Session1: 'string',
+ Session1Date: faker.date.future({ years: 1 }).toString(),
+ Session1DateUtc: faker.date.future({ years: 1 }).toString(),
+ Session2: 'string',
+ Session2Date: faker.date.future({ years: 1 }).toString(),
+ Session2DateUtc: faker.date.future({ years: 1 }).toString(),
+ Session3: 'string',
+ Session3Date: faker.date.future({ years: 1 }).toString(),
+ Session3DateUtc: faker.date.future({ years: 1 }).toString(),
+ Session4: 'string',
+ Session4Date: faker.date.future({ years: 1 }).toString(),
+ Session4DateUtc: faker.date.future({ years: 1 }).toString(),
+ Session5: 'string',
+ Session5Date: faker.date.future({ years: 1 }).toString(),
+ Session5DateUtc: faker.date.future({ years: 1 }).toString(),
+ F1ApiSupport: true,
+ })),
+ },
drivers: [
'All Drivers',
'Drive 1',
diff --git a/src/utils/helpers.tsx b/src/utils/helpers.tsx
index 713f2c1..c8b31e0 100644
--- a/src/utils/helpers.tsx
+++ b/src/utils/helpers.tsx
@@ -122,7 +122,7 @@ export const fetchAPI = async (
const options = statusCheck ? { headers: { cache: 'no-store' } } : {};
// Get dummy data or return false
- const dummy: string[] | ScheduleSchema[] | false =
+ const dummy: string[] | DataConfigSchema['schedule'] | false =
dataConfig[
endpoint.split('?')[0] as 'seasons' | 'schedule' | 'drivers' | 'sessions'
] || false;
@@ -154,8 +154,13 @@ export const fetchAPI = async (
.then((data) => data)
// Catch errors from above
.catch((err) => {
+ // Handle server not connecting error
if (err === 'Server not connecting') return dummy;
- if (err.status === 404) return dummy;
+
+ // Handle api errors
+ if (err.cause.status === 422) {
+ return err.cause.json();
+ }
return dummy;
});