nextjs-exception-grabber
v1.0.0
Published
An exception and log grabber for Next.js applications and PM2 processes that routes details to Discord.
Maintainers
Readme
Next.js Exception Grabber
An aesthetic, robust, and lightweight npm package that intercepts errors, uncaught exceptions, unhandled rejections, API route errors, and PM2 logs across your Next.js application, forwarding them to a Discord channel via Webhooks with rich layouts and automated rate-limiting protection.
Features
- 🚨 Server-side Grabber: Hooks into Node.js process events (
uncaughtException,unhandledRejection) and Next.js 15onRequestErrorinstrumentation. - 🍊 Client-side Grabber: Captures global window errors and unhandled promise rejections.
- 💥 React Error Boundary: A premium
<DiscordErrorBoundary>component to catch rendering errors inside UI segments. - 👾 PM2 Log Monitor: A standalone CLI utility that programmatically streams
stderr(and optionallystdout) logs from PM2 processes. - ⚡ Discord Webhook Batching: Protects against Discord's
429 Too Many Requestsrate limits by queueing and batching messages (up to 10 embeds per message). - 🎨 Rich Formatting: Organizes logs into high-visibility colored Discord embeds containing environment details, stack traces, request URLs, and browser user-agents.
Installation
Install the package in your Next.js project:
npm install nextjs-exception-grabberSetup & Integration
1. Server-side Integration (Next.js 15+ Instrumentation)
Create or update your instrumentation.ts (or instrumentation.js) in the root (or src/) directory:
import { createRequestErrorHandler, initServerGrabber } from 'nextjs-exception-grabber';
const config = {
webhookUrl: process.env.DISCORD_WEBHOOK_URL || '',
environment: process.env.NODE_ENV || 'production',
appName: 'My Next.js App (Server)',
};
export async function register() {
// Initialize global process-level grabbers
if (process.env.NEXT_RUNTIME === 'nodejs') {
initServerGrabber(config);
}
}
// Next.js 15 hook to intercept router/API/Server Action exceptions
export const onRequestError = createRequestErrorHandler(config);Note: Make sure you have
experimental.instrumentationHookenabled in yournext.config.jsif you are on an older Next.js 13/14 version.
2. Client-side Integration
To intercept global runtime client errors, initialize the grabber at your application's entry point (e.g. inside a client component in your root layout):
// app/client-initializer.tsx
'use client';
import { useEffect } from 'react';
import { initClientGrabber } from 'nextjs-exception-grabber/client';
export function ClientInitializer() {
useEffect(() => {
initClientGrabber({
webhookUrl: process.env.NEXT_PUBLIC_DISCORD_WEBHOOK_URL || '',
environment: process.env.NEXT_PUBLIC_APP_ENV || 'production',
appName: 'My Next.js App (Client)',
});
}, []);
return null;
}Include it in your layout:
// app/layout.tsx
import { ClientInitializer } from './client-initializer';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<ClientInitializer />
{children}
</body>
</html>
);
}3. React Error Boundary
You can wrap parts of your application layout or specific features with <DiscordErrorBoundary> to catch component crashes and present an aesthetic fallback UI:
'use client';
import { DiscordErrorBoundary } from 'nextjs-exception-grabber/client';
const config = {
webhookUrl: process.env.NEXT_PUBLIC_DISCORD_WEBHOOK_URL || '',
appName: 'My Next.js App (UI)',
};
export default function DashboardLayout({ children }) {
return (
<DiscordErrorBoundary
config={config}
fallback={<div>Something crashed, but we are looking into it!</div>}
>
<main>{children}</main>
</DiscordErrorBoundary>
);
}4. Manual Exception Capturing
If you want to manually catch and report errors inside try/catch blocks:
Server-side (API Routes, Server Actions, getServerSideProps)
import { captureServerException } from 'nextjs-exception-grabber';
try {
// logic code
} catch (error) {
captureServerException(
{ webhookUrl: process.env.DISCORD_WEBHOOK_URL! },
error,
{ source: 'PaymentProcess' } // extra contextual details
);
}Client-side (React Components, client actions)
import { captureClientException } from 'nextjs-exception-grabber/client';
try {
// client logic
} catch (error) {
captureClientException(
{ webhookUrl: process.env.NEXT_PUBLIC_DISCORD_WEBHOOK_URL! },
error,
{ component: 'SignUpForm' }
);
}5. PM2 Log Monitor CLI
You can stream logs directly from your PM2-managed servers to Discord.
CLI Usage
Run it immediately:
npx nextjs-exception-grabber-pm2 --webhook <discord_webhook_url>CLI Parameters
-w, --webhook <url>: Discord Webhook URL (can also be set viaDISCORD_WEBHOOK_URLenv var).-a, --apps <names>: Comma-separated list of process names to monitor (e.g.my-app,api-gateway). Defaults to all processes.-e, --env <env>: Environment label to show in embeds (e.g.staging). Defaults toproduction.-n, --name <name>: Monitor label to display on Discord footer. Defaults toPM2 Monitor.-o, --include-out: Includesstdoutlogs (default is onlystderrlogs, which prevents webhook spamming).
Run Monitor Continuously in Background with PM2
To keep the Discord log forwarder running persistently under PM2 supervision:
pm2 start "npx nextjs-exception-grabber-pm2" --name "discord-log-forwarder" -- --webhook "https://discord.com/api/webhooks/..." --apps "my-next-app"This starts a light background worker process that hooks into the PM2 internal RPC system, captures stderr, batches them, and delivers them directly to Discord.
License
MIT
