How to handle NextJS errors like a Pro

Whenever I work with NextJS projects, I find it confusing and frustrating 😤 how to handle errors. As we know, if we don’t handle errors properly, our app will crash 💥 which results in a poor user experience and is a very bad practice.
Catching app errors is also essential for logging so we can see which part of our site is not working.
So today we are going to see how to be a pro 🚀 Next.js developer so your application doesn’t crash.
First, let’s see how to handle errors in NextJS.
We all know NextJS says that we should create an error.tsx file, which can be created in the root or other folders. The nearest error boundary will catch the error and display the error page. The problem with this approach is that if our home page is fetching many API endpoints and even one API query fails, the whole site will crash and the user has to reload. If the issue persists, now the whole home page is not usable.
What… is the solution 💡
The solution is to use try-catch, yes you heard that right! Let me explain. First, we have to acknowledge that there are two ways to fetch data in Next.js apps - either server-side or client-side. Let’s see how to handle errors on the server side first, then on the client-side.
Handling errors while fetching data on the server side
Generally, we make a fetcher function and then consume that function in the main function with the help of async/await. We are also going to do the same thing, but this time we will throw an error if !res.ok and in our main function, we are going to use try-catch.
Here’s the code in action:
// Fetch Collections
const fetchCollections = async () => {
const res = await fetch(`https://example.com/collections`, {
next: { revalidate: 24 * 60 * 60 },
cache: 'force-cache',
})
if (!res.ok) {
throw new Error('Failed to fetch categories API')
}
return res.json()
}// Collection List Section
const CollectionSection = async () => {
try {
const { data: collections } = await fetchCollections()
// if res.ok then this section will render
return <Card data={collections} />
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
// if !res.ok then this section will render
return (
<ErrorMessage className='min-h-[10vh] w-[500px]' message={errorMessage} />
)
}
}Now in the above code, if something goes wrong, only the categories section will not be working, but other sections are working fine. This way we saved our application from crashing ✅, caught the error, and the user is still able to explore other sections.
Let’s see how we can handle the same kind of error while fetching data on the client side.
Handling errors while fetching data on the client side
For the client side, we are going to use the npm package react-error-boundary . So suppose we have a cart page, first we will create an error-boundary.tsx component.
import { ReactNode } from 'react'
import { ErrorBoundary } from 'react-error-boundary'
import { ErrorMessage } from './error-message'
export function ErrorBoundaryWrapper({ children }: { children?: ReactNode }) {
return (
<ErrorBoundary
FallbackComponent={(props) => (
<ErrorMessage
message={props.error.message}
onRetry={props.resetErrorBoundary}
/>
)}
>
{children}
</ErrorBoundary>
)
}Okay, we have created the error boundary wrapper and let’s see how we can integrate it with our cart page.
import { ErrorBoundaryWrapper } from './error-boundary'
const CartPage = () => {
return (
<ErrorBoundaryWrapper>
<CartContent />
</ErrorBoundaryWrapper>
)
}
const CartContent = () => {
const fetchCart = async () => {
const res = await fetch(`https://example.com/cart`,)
if (!res.ok) {
// when we throw error from here this error will get catch by our errorboundary
throw new Error('Failed to fetch Cart API')
}
return res.json()
}
return // here you can map on your data
Above is what we are doing - fetching data from the cart, and if something goes wrong here, hopefully the error will get caught by our error boundary.
But still create one NextJS error file in the root so in case we forgot to handle an error somewhere or something unexpected happens, it’s better to show an error page instead of a white screen.
Conclusion 🎉
I hope today you learned something new. If you found this article useful or you think there is a better way, you can write that approach in the comments so it helps others as well.
Bye for now …
Comments
Leave a comment or reaction below!