Error Handling and Logging
Introduction
Error handling and logging are essential for building robust and maintainable frontend applications. They help identify, debug, and address issues effectively. In this project, built with Next.js, TailwindCSS, and TypeScript, proper error handling and structured logging can ensure a smoother development process and a better user experience.
Error Handling
Types of Errors
- Client-Side Errors: Errors occurring in the browser, often due to invalid user input or code issues.
- Server-Side Errors: Errors originating from backend services, such as API failures or database issues.
- Network Errors: Errors caused by failed requests, slow connections, or timeouts.
Handling Errors in Next.js
Error Boundaries
Use React error boundaries to catch JavaScript errors in components.
Example:
import React from "react";
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error: Error, info: React.ErrorInfo) {
console.error("Error caught by boundary:", error, info);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary;
Wrap critical components with the ErrorBoundary
component:
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
Custom Error Pages
Create a custom _error.js
file in the pages
directory to handle errors globally.
Example:
import React from "react";
function CustomError({ statusCode }: { statusCode?: number }) {
return (
<p>
{statusCode
? `An error ${statusCode} occurred on the server`
: "An error occurred on the client"}
</p>
);
}
CustomError.getInitialProps = ({ res, err }: any) => {
const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
return { statusCode };
};
export default CustomError;
Handling API Errors
Catch and handle errors when making API calls.
Example:
async function fetchData(url: string) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("API call failed:", error);
throw error;
}
}
Logging
Why Logging is Important
Logging provides visibility into application behavior, helping developers identify and debug issues efficiently.
Tools for Logging
- Console Logging: Use
console.log
,console.warn
, andconsole.error
during development. Remove or minimize these in production. - Logging Libraries: Use libraries like
winston
orpino
for structured logging.
Logging in Next.js
Use next-logger
for a simple logging setup in a Next.js project.
Installation
npm install next-logger
Basic Usage
import logger from "next-logger";
logger.info("This is an info message");
logger.error("This is an error message");
debug
Structured Logging with Install the debug
library:
npm install debug
Use it in your project:
import debug from "debug";
const log = debug("app:component");
log("This is a debug message");
Enable debug logs in development:
DEBUG=app:* npm run dev
Monitoring Tools
Sentry
Sentry is a popular error tracking and monitoring tool.
Installation
npm install @sentry/nextjs
Configuration
Add the following to sentry.server.config.js
and sentry.client.config.js
:
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "your-dsn-url",
tracesSampleRate: 1.0,
});
LogRocket
LogRocket captures logs, errors, and user sessions for advanced debugging.
Installation
npm install logrocket
Usage
import LogRocket from "logrocket";
LogRocket.init("your-app-id");
Best Practices for Error Handling and Logging
- Catch and handle errors gracefully without exposing sensitive information to users.
- Use structured logging to provide context about errors.
- Monitor logs and errors in real-time using tools like Sentry or LogRocket.
- Use error boundaries to prevent the app from crashing due to unexpected errors.
- Regularly review and improve logging practices as the application evolves.
With effective error handling and logging, you can build a more resilient and maintainable Next.js application. Always strive for meaningful logs and robust error management. Happy coding!