Skip to content

Commit

Permalink
Merge pull request #55 from vim/make-fe-more-resilient
Browse files Browse the repository at this point in the history
Make fe more resilient
  • Loading branch information
manuel-pross authored Aug 6, 2024
2 parents 3554637 + 26b7c68 commit 060d4da
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 35 deletions.
7 changes: 2 additions & 5 deletions web/src/app/[...slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import { notFound } from "next/navigation";
import { getPageContent } from "@/helpers/getPageContent";

export default async function page({ params }: { params: { slug: string[] } }) {
Expand All @@ -10,10 +11,6 @@ export default async function page({ params }: { params: { slug: string[] } }) {
</div>
);
} catch (e) {
return (
<div>
<p>No content defined in CMS.</p>
</div>
);
notFound();
}
}
33 changes: 29 additions & 4 deletions web/src/app/api/[homepage]/route.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { notFound, redirect } from "next/navigation";
import { getNews } from "@/helpers/homepage";
import { SingleType } from "@/types/strapi";

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

if (!res.ok) {
handleHTTPError(res.status);
throw new Error("Fetching single type component home failed");
}

const homePageData = (await res.json()) as SingleType;
let homePageData: SingleType;

if (!homePageData.data.attributes.body) {
try {
homePageData = (await res.json()) as SingleType;
} catch (e) {
throw new Error("Failed to parse homepage data");
}

if (!homePageData?.data.attributes.body) {
return Response.json("Homepage contains no data");
}

if (!Array.isArray(homePageData?.data?.attributes?.body)) {
return Response.json("Body has no content");
}

const newsSections = homePageData.data.attributes.body.flatMap((contentEntry, i) => {
if ("newsCount" in contentEntry) return { index: i, newsCount: contentEntry.newsCount, headline: contentEntry.headline };
else return [];
if ("newsCount" in contentEntry && "headline" in contentEntry) {
return { index: i, newsCount: contentEntry.newsCount, headline: contentEntry.headline };
}
return [];
});

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

return Response.json(homePageData.data.attributes);
}

function handleHTTPError(errorCode: number) {
switch (errorCode) {
case 400:
return notFound();
case 500:
return redirect("/error/500");
default:
throw new Error("Fetching homepage data failed with status: " + errorCode);
}
}
3 changes: 3 additions & 0 deletions web/src/app/error/500/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Custom500() {
return <h1 className="h1">Something went wrong. Pls try again later.</h1>;
}
31 changes: 22 additions & 9 deletions web/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { redirect } from "next/navigation";
import { Fira_Code } from "next/font/google";
import { getServerSession } from "next-auth";
import type { Metadata } from "next";
Expand Down Expand Up @@ -28,21 +29,33 @@ async function getPageProps() {
const query = qs.stringify(params, { addQueryPrefix: true });

try {
const response = await fetch(`${process.env.CMS_API}/menus/1${query}`, {
// headers: {
// authorization: `Bearer ${process.env.CMS_TOKEN}`,
// },
});

return (await response.json()).data.attributes.items.data;
const response = await fetch(`${process.env.CMS_API}/menus/1${query}`);
if (!response.ok) {
throw new Error(`Failed to fetch data: ${response.status} ${response.statusText}`);
}
const data = await response.json();
return data.data.attributes.items.data;
} catch (error) {
return [];
}
}

export default async function RootLayout({ children }: { children: React.ReactNode }) {
const pageProps = await getPageProps();
const session = await getServerSession();
const pageProps = [];
let session = null;

try {
const props = await getPageProps();
pageProps.push(...props);
} catch (error) {
redirect("/error/500");
}

try {
session = await getServerSession();
} catch (error) {
redirect("/error/500");
}

return (
<SessionProvider session={session}>
Expand Down
12 changes: 12 additions & 0 deletions web/src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Link from "next/link";

export default function NotFound() {
return (
<div>
<h1 className="h1">Resource not found!</h1>
<Link className="link" href="/">
Return Home
</Link>
</div>
);
}
8 changes: 7 additions & 1 deletion web/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"use client";
import { redirect } from "next/navigation";
import Error from "next/error";
import useSWR from "swr";
import Hero from "@/components/Strapi/Sections/HeroSection";
import PageContent from "@/components/Strapi/Sections/Content";
Expand All @@ -7,7 +9,11 @@ import { PageAttributes, Routes } from "@/types/strapi";
const fetcher = (url: string) => fetch(url).then(res => res.json() as Promise<PageAttributes>);

export default function Home() {
const { data } = useSWR(`/api/${Routes.homepage}`, fetcher);
const { data, error } = useSWR<PageAttributes, Error>(`/api/${Routes.homepage}`, fetcher);

if (error) {
redirect("/error/500");
}

return (
<main className="pb-12">
Expand Down
50 changes: 37 additions & 13 deletions web/src/helpers/getPageContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,44 @@ export async function getPageContent(slug: string[]) {
},
},
};

const query = qs.stringify(params, { addQueryPrefix: true });
const respose = await fetch(`${process.env.CMS_API}/menus/1${query}`, {
// headers: {
// authorization: `Bearer ${process.env.CMS_TOKEN}`,
// },
});
const data = (await respose.json()).data;
const page = data.attributes.items.data.find((item: { attributes: { url: string } }) => item.attributes.url.endsWith(slug[0]));
const pageRelation = page?.attributes?.page_relation.data;

let pageContent;
if (pageRelation) {
let response, data, page, pageRelation, pageContent;

try {
response = await fetch(`${process.env.CMS_API}/menus/1${query}`, {
// headers: {
// authorization: `Bearer ${process.env.CMS_TOKEN}`,
// },
});

if (!response.ok) {
throw new Error(`Failed to fetch menu data: ${response.statusText}`);
}

data = await response.json();
} catch (error) {
return { error: "Failed to fetch menu data" };
}

try {
page = data?.data?.attributes?.items?.data?.find((item: { attributes: { url: string } }) => item?.attributes?.url?.endsWith(slug[0]));
pageRelation = page?.attributes?.page_relation?.data;

if (!pageRelation) {
throw new Error("Page relation not found");
}

const pageRes = await fetch(`${process.env.CMS_API}/pages/${pageRelation.id}?populate=*`);
pageContent = (await pageRes.json()).data;

if (!pageRes.ok) {
throw new Error(`Failed to fetch page data: ${pageRes.statusText}`);
}

pageContent = await pageRes.json();
} catch (error) {
return { error: "Failed to fetch page data" };
}
return { page: pageContent };

return { page: pageContent.data };
}
4 changes: 2 additions & 2 deletions web/src/helpers/homepage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ export async function getNews(count: number = 5): Promise<NewsCollection> {
const query = qs.stringify(
{
pagination: {
pageSize: count,
page: 1,
limit: count,
},
},
{
encodeValuesOnly: true,
}
);

const response = await fetch(`${process.env.CMS_API}/newsposts?${query}`);

if (!response.ok) {
Expand Down
2 changes: 1 addition & 1 deletion web/src/lib/auth/strapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const signUp = async (username: string, email: string, password: string,
});

return await response.json();
} catch {
} catch (e) {
return null;
}
};

0 comments on commit 060d4da

Please sign in to comment.