Last checked with Wasp 0.23, @sentry/node 8, and @sentry/react 8.
This guide depends on external libraries or services, so it may become outdated over time. We do our best to keep it up to date, but make sure to check their documentation for any changes.Sentry
This guide shows you how to integrate Sentry into your Wasp application for error tracking on both the server and client.
Prerequisites
- A Wasp project set up
- A Sentry account
Setting up Sentry
1. Create Sentry Projects
You'll need to create two projects in Sentry:
- Server project: Select
Node.jsas the platform andExpressas the framework - Client project: Select
Reactas the platform
After creating each project, you'll receive a unique DSN (Data Source Name) that you'll use to configure Sentry.
2. Install Sentry packages
Install the Sentry SDKs:
npm install @sentry/node @sentry/react
3. Configure your Wasp file
Add both the server and client setup functions to your main.wasp:
app MyApp {
wasp: {
version: "^0.21.0"
},
title: "my-app",
server: {
setupFn: import { setupServer } from "@src/serverSetup"
},
client: {
setupFn: import { setupClient } from "@src/clientSetup"
},
}
4. Configure Server-Side Sentry
Create the server setup file:
- JavaScript
- TypeScript
import * as Sentry from "@sentry/node";
import { ServerSetupFn } from "wasp/server";
Sentry.init({
dsn: process.env.SENTRY_SERVER_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 1.0,
});
export const setupServer = async ({ app }) => {
Sentry.setupExpressErrorHandler(app);
};
import * as Sentry from "@sentry/node";
import { ServerSetupFn } from "wasp/server";
Sentry.init({
dsn: process.env.SENTRY_SERVER_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 1.0,
});
export const setupServer: ServerSetupFn = async ({ app }) => {
Sentry.setupExpressErrorHandler(app);
};
Find your DSN in Sentry under Settings > Client Keys (DSN).
5. Configure Client-Side Sentry
Create the client setup file:
- JavaScript
- TypeScript
import * as Sentry from "@sentry/react";
Sentry.init({
dsn: import.meta.env.REACT_APP_SENTRY_CLIENT_DSN,
environment: import.meta.env.MODE,
tracesSampleRate: 1.0,
});
export const setupClient = async () => {
// Sentry is initialized above, before the setup function runs.
// You can add additional client-side setup here if needed.
};
import * as Sentry from "@sentry/react";
Sentry.init({
dsn: import.meta.env.REACT_APP_SENTRY_CLIENT_DSN,
environment: import.meta.env.MODE,
tracesSampleRate: 1.0,
});
export const setupClient = async () => {
// Sentry is initialized above, before the setup function runs.
// You can add additional client-side setup here if needed.
};
The setupFn must be defined and exported even if it has no additional logic. Sentry's init call runs at module load time, which is before Wasp calls the setup function.
6. Set up environment variables
Add to your .env.server:
SENTRY_SERVER_DSN=https://your-server-dsn@sentry.io/your-project-id
Add to your .env.client:
REACT_APP_SENTRY_CLIENT_DSN=https://your-client-dsn@sentry.io/your-project-id
Testing the Integration
Test Server Errors
Create an API endpoint that throws an error:
- JavaScript
- TypeScript
import { TestError } from "wasp/server/api";
export const testError = async (req, res) => {
throw new Error("Test server error for Sentry");
};
import { TestError } from "wasp/server/api";
export const testError: TestError = async (req, res) => {
throw new Error("Test server error for Sentry");
};
Test Client Errors
Add a button that triggers an error:
- JavaScript
- TypeScript
export const MainPage = () => {
const handleError = () => {
throw new Error("Test client error for Sentry");
};
return (
<div>
<button onClick={handleError}>Test Sentry Error</button>
</div>
);
};
export const MainPage = () => {
const handleError = () => {
throw new Error("Test client error for Sentry");
};
return (
<div>
<button onClick={handleError}>Test Sentry Error</button>
</div>
);
};
Advanced Configuration
Adding User Context
Track which user encountered an error:
- JavaScript
- TypeScript
import * as Sentry from "@sentry/node";
// In your API handlers or operations
export const someOperation = async (args, context) => {
if (context.user) {
Sentry.setUser({
id: context.user.id,
email: context.user.email,
});
}
// ...
};
import * as Sentry from "@sentry/node";
// In your API handlers or operations
export const someOperation = async (args, context) => {
if (context.user) {
Sentry.setUser({
id: context.user.id,
email: context.user.email,
});
}
// ...
};
Performance Monitoring
Enable performance monitoring:
- JavaScript
- TypeScript
Sentry.init({
dsn: "your-dsn",
tracesSampleRate: 0.1, // Capture 10% of transactions
profilesSampleRate: 0.1, // Capture 10% of profiles (if using profiling)
});
Sentry.init({
dsn: "your-dsn",
tracesSampleRate: 0.1, // Capture 10% of transactions
profilesSampleRate: 0.1, // Capture 10% of profiles (if using profiling)
});
Error Boundaries (React)
Use Sentry's error boundary for React:
- JavaScript
- TypeScript
import * as Sentry from "@sentry/react";
export const App = ({ children }) => {
return (
<Sentry.ErrorBoundary fallback={<p>An error occurred</p>}>
{children}
</Sentry.ErrorBoundary>
);
};
import * as Sentry from "@sentry/react";
export const App = ({ children }) => {
return (
<Sentry.ErrorBoundary fallback={<p>An error occurred</p>}>
{children}
</Sentry.ErrorBoundary>
);
};
For more configuration options, see the Sentry documentation.