Skip to content

Commit 6ff31eb

Browse files
AnikaAnika
authored andcommitted
fix: prevent crashes when blogPosts is empty or calendar fetch fails
Issue: Runtime crashes when blogPosts array is empty or calendar fetch fails Kind of change: Bug fix (fixes runtime crashes) Description: - Add null checks for blogPosts array before accessing first element - Add safe array access with fallback to empty array for datesInfo - Add proper error handling with try-catch for calendar data fetching - Add TypeScript type annotations for datesInfo to prevent type errors - Wrap blog post section in conditional rendering to prevent crashes - Both homepage and community page now handle empty data gracefully Files modified: - pages/index.page.tsx - pages/community/index.page.tsx
1 parent 1a2d4a6 commit 6ff31eb

File tree

2 files changed

+201
-159
lines changed

2 files changed

+201
-159
lines changed

pages/community/index.page.tsx

Lines changed: 97 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,23 @@ export const getStaticProps: GetStaticProps = async () => {
4040

4141
const remoteICalUrl =
4242
'https://calendar.google.com/calendar/ical/json.schema.community%40gmail.com/public/basic.ics';
43-
const datesInfo = await fetchRemoteICalFile(remoteICalUrl)
44-
.then((icalData: any) => printEventsForNextWeeks(ical.parseICS(icalData)))
45-
.catch((error) => console.error('Error:', error));
43+
let datesInfo: Array<{
44+
title: string;
45+
time: string;
46+
day: string;
47+
timezone: string;
48+
parsedStartDate: string;
49+
}> = [];
50+
try {
51+
const icalData = await fetchRemoteICalFile(remoteICalUrl);
52+
if (icalData) {
53+
const parsedData = ical.parseICS(icalData);
54+
datesInfo = printEventsForNextWeeks(parsedData) || [];
55+
}
56+
} catch (error) {
57+
console.error('Error processing calendar data:', error);
58+
// datesInfo defaults to empty array to prevent crashes
59+
}
4660
return {
4761
props: {
4862
blogPosts,
@@ -53,8 +67,11 @@ export const getStaticProps: GetStaticProps = async () => {
5367
};
5468

5569
export default function communityPages(props: any) {
56-
const blogPosts = props.blogPosts;
57-
const timeToRead = Math.ceil(readingTime(blogPosts[0].content).minutes);
70+
const blogPosts = props.blogPosts || [];
71+
const firstBlogPost = blogPosts[0];
72+
const timeToRead = firstBlogPost
73+
? Math.ceil(readingTime(firstBlogPost.content).minutes)
74+
: 0;
5875

5976
return (
6077
<SectionContext.Provider value='community'>
@@ -248,7 +265,7 @@ export default function communityPages(props: any) {
248265
<h2 className='text-center dark:text-white text-primary text-[2rem] font-bold '>
249266
Upcoming events
250267
</h2>
251-
{props.datesInfo.map((event: any, index: any) => (
268+
{(props.datesInfo || []).map((event: any, index: any) => (
252269
<div
253270
key={index}
254271
className='mx-auto gap-2 group-hover:bg-white dark:bg-slate-900/50 dark:group-hover:bg-slate-800 bg-slate-100 h-[90px] max-md:h-[120px] max-sm:h-auto w-full rounded-lg flex flex-row justify-between items-center p-2 mt-2'
@@ -309,83 +326,86 @@ export default function communityPages(props: any) {
309326
</div>
310327
</div>
311328
</div>
312-
<div className='p-10 flex justify-between w-full md:w-3/6 h-auto flex-col text-center md:text-left '>
313-
<div className='w-full mb-6 '>
314-
<Link href={`/blog/posts/${blogPosts[0].slug}`}>
315-
<Image
316-
src={blogPosts[0].frontmatter.cover}
317-
className='w-full h-[232px] mb-4'
318-
height={232}
319-
width={400}
320-
alt={blogPosts[0].frontmatter.title}
321-
/>
322-
<h3 className='mb-4 font-semibold dark:text-white'>
323-
{blogPosts[0].frontmatter.title}
324-
</h3>
325-
<div className='mb-4 text-[14px] dark:text-white'>
326-
<TextTruncate
327-
element='span'
328-
line={4}
329-
text={blogPosts[0].frontmatter.excerpt}
329+
{firstBlogPost && (
330+
<div className='p-10 flex justify-between w-full md:w-3/6 h-auto flex-col text-center md:text-left '>
331+
<div className='w-full mb-6 '>
332+
<Link href={`/blog/posts/${firstBlogPost.slug}`}>
333+
<Image
334+
src={firstBlogPost.frontmatter.cover}
335+
className='w-full h-[232px] mb-4'
336+
height={232}
337+
width={400}
338+
alt={firstBlogPost.frontmatter.title}
330339
/>
331-
</div>
332-
<div className='flex ml-2 mb-2 '>
333-
{(blogPosts[0].frontmatter.authors || []).map(
334-
(author: any, index: number) => {
335-
return (
336-
<div
337-
key={index}
338-
className='bg-slate-50 h-[44px] w-[44px] rounded-full -ml-3 bg-cover bg-center border-2 border-white'
339-
style={{
340-
backgroundImage: `url(${author.photo})`,
341-
zIndex: 10 - index,
342-
}}
343-
/>
344-
);
345-
},
346-
)}
347-
<div className='flex flex-col ml-2'>
348-
<p className='text-sm font-semibold dark:text-white'>
349-
{blogPosts[0].frontmatter.authors.length > 2 ? (
350-
<>
351-
{blogPosts[0].frontmatter.authors
352-
.slice(0, 2)
353-
.map((author: any, index: number) => (
354-
<span key={author.name}>
355-
{author.name}
356-
{index === 0 && ' & '}
357-
</span>
358-
))}
359-
{'...'}
360-
</>
361-
) : (
362-
blogPosts[0].frontmatter.authors.map(
363-
(author: any) => (
364-
<span key={author.name}>{author.name}</span>
365-
),
366-
)
367-
)}
368-
</p>
369-
<div className='dark:text-slate-300 text-sm'>
370-
<span>
371-
{blogPosts[0].frontmatter.date} &middot;{timeToRead}{' '}
372-
min min read
373-
</span>
340+
<h3 className='mb-4 font-semibold dark:text-white'>
341+
{firstBlogPost.frontmatter.title}
342+
</h3>
343+
<div className='mb-4 text-[14px] dark:text-white'>
344+
<TextTruncate
345+
element='span'
346+
line={4}
347+
text={firstBlogPost.frontmatter.excerpt}
348+
/>
349+
</div>
350+
<div className='flex ml-2 mb-2 '>
351+
{(firstBlogPost.frontmatter.authors || []).map(
352+
(author: any, index: number) => {
353+
return (
354+
<div
355+
key={index}
356+
className='bg-slate-50 h-[44px] w-[44px] rounded-full -ml-3 bg-cover bg-center border-2 border-white'
357+
style={{
358+
backgroundImage: `url(${author.photo})`,
359+
zIndex: 10 - index,
360+
}}
361+
/>
362+
);
363+
},
364+
)}
365+
<div className='flex flex-col ml-2'>
366+
<p className='text-sm font-semibold dark:text-white'>
367+
{firstBlogPost.frontmatter.authors &&
368+
firstBlogPost.frontmatter.authors.length > 2 ? (
369+
<>
370+
{firstBlogPost.frontmatter.authors
371+
.slice(0, 2)
372+
.map((author: any, index: number) => (
373+
<span key={author.name}>
374+
{author.name}
375+
{index === 0 && ' & '}
376+
</span>
377+
))}
378+
{'...'}
379+
</>
380+
) : (
381+
firstBlogPost.frontmatter.authors?.map(
382+
(author: any) => (
383+
<span key={author.name}>{author.name}</span>
384+
),
385+
) || []
386+
)}
387+
</p>
388+
<div className='dark:text-slate-300 text-sm'>
389+
<span>
390+
{firstBlogPost.frontmatter.date} &middot;
391+
{timeToRead} min min read
392+
</span>
393+
</div>
374394
</div>
375395
</div>
376-
</div>
377-
</Link>
378-
<div className='mx-auto '>
379-
<Link
380-
href='/blog'
381-
rel='noopener noreferrer'
382-
className='bg-blue-700 hover:bg-blue-800 text-white font-bold py-2 px-4 rounded block md:inline-block focus:outline-none mt-4'
383-
>
384-
Read more posts
385396
</Link>
397+
<div className='mx-auto '>
398+
<Link
399+
href='/blog'
400+
rel='noopener noreferrer'
401+
className='bg-blue-700 hover:bg-blue-800 text-white font-bold py-2 px-4 rounded block md:inline-block focus:outline-none mt-4'
402+
>
403+
Read more posts
404+
</Link>
405+
</div>
386406
</div>
387407
</div>
388-
</div>
408+
)}
389409
</div>
390410
</div>
391411
</div>

0 commit comments

Comments
 (0)