Skip to content
This repository was archived by the owner on Jun 28, 2025. It is now read-only.

Commit 060d4da

Browse files
authored
Merge pull request #55 from vim/make-fe-more-resilient
Make fe more resilient
2 parents 3554637 + 26b7c68 commit 060d4da

File tree

9 files changed

+115
-35
lines changed

9 files changed

+115
-35
lines changed

web/src/app/[...slug]/page.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react";
2+
import { notFound } from "next/navigation";
23
import { getPageContent } from "@/helpers/getPageContent";
34

45
export default async function page({ params }: { params: { slug: string[] } }) {
@@ -10,10 +11,6 @@ export default async function page({ params }: { params: { slug: string[] } }) {
1011
</div>
1112
);
1213
} catch (e) {
13-
return (
14-
<div>
15-
<p>No content defined in CMS.</p>
16-
</div>
17-
);
14+
notFound();
1815
}
1916
}

web/src/app/api/[homepage]/route.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { notFound, redirect } from "next/navigation";
12
import { getNews } from "@/helpers/homepage";
23
import { SingleType } from "@/types/strapi";
34

@@ -9,18 +10,31 @@ export async function GET() {
910
});
1011

1112
if (!res.ok) {
13+
handleHTTPError(res.status);
1214
throw new Error("Fetching single type component home failed");
1315
}
1416

15-
const homePageData = (await res.json()) as SingleType;
17+
let homePageData: SingleType;
1618

17-
if (!homePageData.data.attributes.body) {
19+
try {
20+
homePageData = (await res.json()) as SingleType;
21+
} catch (e) {
22+
throw new Error("Failed to parse homepage data");
23+
}
24+
25+
if (!homePageData?.data.attributes.body) {
1826
return Response.json("Homepage contains no data");
1927
}
2028

29+
if (!Array.isArray(homePageData?.data?.attributes?.body)) {
30+
return Response.json("Body has no content");
31+
}
32+
2133
const newsSections = homePageData.data.attributes.body.flatMap((contentEntry, i) => {
22-
if ("newsCount" in contentEntry) return { index: i, newsCount: contentEntry.newsCount, headline: contentEntry.headline };
23-
else return [];
34+
if ("newsCount" in contentEntry && "headline" in contentEntry) {
35+
return { index: i, newsCount: contentEntry.newsCount, headline: contentEntry.headline };
36+
}
37+
return [];
2438
});
2539

2640
for (const newsSectionEntry of newsSections) {
@@ -31,3 +45,14 @@ export async function GET() {
3145

3246
return Response.json(homePageData.data.attributes);
3347
}
48+
49+
function handleHTTPError(errorCode: number) {
50+
switch (errorCode) {
51+
case 400:
52+
return notFound();
53+
case 500:
54+
return redirect("/error/500");
55+
default:
56+
throw new Error("Fetching homepage data failed with status: " + errorCode);
57+
}
58+
}

web/src/app/error/500/page.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Custom500() {
2+
return <h1 className="h1">Something went wrong. Pls try again later.</h1>;
3+
}

web/src/app/layout.tsx

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { redirect } from "next/navigation";
12
import { Fira_Code } from "next/font/google";
23
import { getServerSession } from "next-auth";
34
import type { Metadata } from "next";
@@ -28,21 +29,33 @@ async function getPageProps() {
2829
const query = qs.stringify(params, { addQueryPrefix: true });
2930

3031
try {
31-
const response = await fetch(`${process.env.CMS_API}/menus/1${query}`, {
32-
// headers: {
33-
// authorization: `Bearer ${process.env.CMS_TOKEN}`,
34-
// },
35-
});
36-
37-
return (await response.json()).data.attributes.items.data;
32+
const response = await fetch(`${process.env.CMS_API}/menus/1${query}`);
33+
if (!response.ok) {
34+
throw new Error(`Failed to fetch data: ${response.status} ${response.statusText}`);
35+
}
36+
const data = await response.json();
37+
return data.data.attributes.items.data;
3838
} catch (error) {
3939
return [];
4040
}
4141
}
4242

4343
export default async function RootLayout({ children }: { children: React.ReactNode }) {
44-
const pageProps = await getPageProps();
45-
const session = await getServerSession();
44+
const pageProps = [];
45+
let session = null;
46+
47+
try {
48+
const props = await getPageProps();
49+
pageProps.push(...props);
50+
} catch (error) {
51+
redirect("/error/500");
52+
}
53+
54+
try {
55+
session = await getServerSession();
56+
} catch (error) {
57+
redirect("/error/500");
58+
}
4659

4760
return (
4861
<SessionProvider session={session}>

web/src/app/not-found.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import Link from "next/link";
2+
3+
export default function NotFound() {
4+
return (
5+
<div>
6+
<h1 className="h1">Resource not found!</h1>
7+
<Link className="link" href="/">
8+
Return Home
9+
</Link>
10+
</div>
11+
);
12+
}

web/src/app/page.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"use client";
2+
import { redirect } from "next/navigation";
3+
import Error from "next/error";
24
import useSWR from "swr";
35
import Hero from "@/components/Strapi/Sections/HeroSection";
46
import PageContent from "@/components/Strapi/Sections/Content";
@@ -7,7 +9,11 @@ import { PageAttributes, Routes } from "@/types/strapi";
79
const fetcher = (url: string) => fetch(url).then(res => res.json() as Promise<PageAttributes>);
810

911
export default function Home() {
10-
const { data } = useSWR(`/api/${Routes.homepage}`, fetcher);
12+
const { data, error } = useSWR<PageAttributes, Error>(`/api/${Routes.homepage}`, fetcher);
13+
14+
if (error) {
15+
redirect("/error/500");
16+
}
1117

1218
return (
1319
<main className="pb-12">

web/src/helpers/getPageContent.ts

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,44 @@ export async function getPageContent(slug: string[]) {
1111
},
1212
},
1313
};
14+
1415
const query = qs.stringify(params, { addQueryPrefix: true });
15-
const respose = await fetch(`${process.env.CMS_API}/menus/1${query}`, {
16-
// headers: {
17-
// authorization: `Bearer ${process.env.CMS_TOKEN}`,
18-
// },
19-
});
20-
const data = (await respose.json()).data;
21-
const page = data.attributes.items.data.find((item: { attributes: { url: string } }) => item.attributes.url.endsWith(slug[0]));
22-
const pageRelation = page?.attributes?.page_relation.data;
23-
24-
let pageContent;
25-
if (pageRelation) {
16+
let response, data, page, pageRelation, pageContent;
17+
18+
try {
19+
response = await fetch(`${process.env.CMS_API}/menus/1${query}`, {
20+
// headers: {
21+
// authorization: `Bearer ${process.env.CMS_TOKEN}`,
22+
// },
23+
});
24+
25+
if (!response.ok) {
26+
throw new Error(`Failed to fetch menu data: ${response.statusText}`);
27+
}
28+
29+
data = await response.json();
30+
} catch (error) {
31+
return { error: "Failed to fetch menu data" };
32+
}
33+
34+
try {
35+
page = data?.data?.attributes?.items?.data?.find((item: { attributes: { url: string } }) => item?.attributes?.url?.endsWith(slug[0]));
36+
pageRelation = page?.attributes?.page_relation?.data;
37+
38+
if (!pageRelation) {
39+
throw new Error("Page relation not found");
40+
}
41+
2642
const pageRes = await fetch(`${process.env.CMS_API}/pages/${pageRelation.id}?populate=*`);
27-
pageContent = (await pageRes.json()).data;
43+
44+
if (!pageRes.ok) {
45+
throw new Error(`Failed to fetch page data: ${pageRes.statusText}`);
46+
}
47+
48+
pageContent = await pageRes.json();
49+
} catch (error) {
50+
return { error: "Failed to fetch page data" };
2851
}
29-
return { page: pageContent };
52+
53+
return { page: pageContent.data };
3054
}

web/src/helpers/homepage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ export async function getNews(count: number = 5): Promise<NewsCollection> {
5050
const query = qs.stringify(
5151
{
5252
pagination: {
53-
pageSize: count,
54-
page: 1,
53+
limit: count,
5554
},
5655
},
5756
{
5857
encodeValuesOnly: true,
5958
}
6059
);
60+
6161
const response = await fetch(`${process.env.CMS_API}/newsposts?${query}`);
6262

6363
if (!response.ok) {

web/src/lib/auth/strapi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export const signUp = async (username: string, email: string, password: string,
3535
});
3636

3737
return await response.json();
38-
} catch {
38+
} catch (e) {
3939
return null;
4040
}
4141
};

0 commit comments

Comments
 (0)