Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

integrating Sentry in Next.js project

I am using Next.js with AMP. That means my code runs only on the server. no client code.

I'm trying to integrate @sentry/node However, while i'm adding this line alone to index.js in /pages const Sentry = require('@sentry/node');

the build fails with the following error:

[ wait ]  compiling ...
[ error ] ./node_modules/@sentry/node/esm/integrations/console.js
Module not found: Can't resolve 'console' in '/Users/lirancohen/Projects/amp-app/node_modules/@sentry/node/esm/integrations'

I would appreciate any help to understand this issue. Using next 9.0.1 and sentry 5.0.5

like image 455
LiranC Avatar asked Jul 25 '19 06:07

LiranC


People also ask

How do you integrate Sentry?

Open your Sentry account and navigate to Settings > Integrations to enable the GitHub integration and add your backend-monitoring repository.

Does Next JS use SWC?

js Compiler introduced. The Next. js Compiler, written in Rust using SWC, allows Next. js to transform and minify your JavaScript code for production.

Is Sentry DSN secret?

The DSN is not a secret, worst thing someone could do is sending events to your account. All “analytics” services have this problem. You can create just a new DSN and delete old ones. You can find this in your project settings -> Client Keys.


2 Answers

For people looking to implement Sentry with Next.js, make sure to check out https://github.com/UnlyEd/next-right-now

Most interesting parts are:

  • https://github.com/UnlyEd/next-right-now/blob/7fd4523e59528dfaaf418b601a3830559360c9d4/src/utils/monitoring/sentry.ts (Sentry config)
  • https://github.com/UnlyEd/next-right-now/blob/b78b03296b9977ef2d9550418219dac0326fbfb1/src/components/appBootstrap/MultiversalAppBootstrap.tsx#L70-L132 (Various Sentry usage)
  • https://github.com/UnlyEd/next-right-now/blob/c2946306e5e4658afafe8525330d003fd61534bb/src/pages/api/error.ts (Sentry to catch errors)
  • https://github.com/UnlyEd/next-right-now/blob/f24da10646f1a8225fed537337193fd0707f7ac1/next.config.js#L237-L254 (universal Sentry)

Disclaimer: I'm one of the project's contributors

Note the above links point to a fix commit to avoid breaking, but you should consider looking at a up-to-date version. Branch: https://github.com/UnlyEd/next-right-now/blob/v2-mst-aptd-at-lcz-sty/


utils/sentry.ts

import { NowRequest } from '@now/node/dist';
import * as Sentry from '@sentry/node';
import get from 'lodash.get';
import { isBrowser } from '@unly/utils';

/**
 * Initialize Sentry and export it.
 *
 * Helper to avoid duplicating the init() call in every /pages/api file.
 * Also used in pages/_app for the client side, which automatically applies it for all frontend pages.
 */
Sentry.init({
  dsn: process.env.SENTRY_DSN,
  enabled: process.env.NODE_ENV !== 'test',
  environment: process.env.APP_STAGE,
  release: process.env.APP_VERSION_RELEASE,
});

if (!process.env.SENTRY_DSN && process.env.NODE_ENV !== 'test') {
  // eslint-disable-next-line no-console
  console.error('Sentry DSN not defined');
}

// Scope configured by default, subsequent calls to "configureScope" will add additional data
Sentry.configureScope((scope) => { // See https://www.npmjs.com/package/@sentry/node
  scope.setTag('nodejs', process.version);
  scope.setTag('nodejsAWS', process.env.AWS_EXECUTION_ENV || null); // Optional - Available on production environment only
  scope.setTag('memory', process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE || null); // Optional - Available on production environment only
  scope.setTag('runtimeEngine', isBrowser() ? 'browser' : 'server');
  scope.setTag('buildTime', process.env.BUILD_TIME);
});

/**
 * Configure the Sentry scope by extracting useful tags and context from the given request.
 *
 * @param req
 */
export const configureReq = (req: NowRequest): void => {
  Sentry.configureScope((scope) => {
    scope.setTag('host', get(req, 'headers.host'));
    scope.setTag('url', get(req, 'url'));
    scope.setTag('method', get(req, 'method'));
    scope.setContext('query', get(req, 'query'));
    scope.setContext('cookies', get(req, 'cookies'));
    scope.setContext('body', get(req, 'body'));
    scope.setContext('headers', get(req, 'headers'));
  });
};

export default Sentry;

Usage examples (pages/_app.tsx):

import * as Sentry from '@sentry/node';
import '../utils/sentry';

//...

Sentry.configureScope((scope) => { // See https://www.npmjs.com/package/@sentry/node
  scope.setTag('customer', customerRef);
  scope.setTag('userId', userSession.id);
  scope.setContext('userSession', userSession);
  scope.setContext('cookies', readonlyCookies);
});

Sentry.addBreadcrumb({ // See https://docs.sentry.io/enriching-error-data/breadcrumbs
  category: fileLabel,
  message: `Preparing app (${isBrowser() ? 'browser' : 'server'})`,
  level: Sentry.Severity.Debug,
});

Webpack config (next.config.js)

webpack: (config, { isServer, buildId }) => {
    // Fixes npm packages that depend on `fs` module
    config.node = {
      fs: 'empty',
    };

    // XXX See https://github.com/zeit/next.js/blob/canary/examples/with-sentry-simple/next.config.js
    // In `pages/_app.js`, Sentry is imported from @sentry/node. While
    // @sentry/browser will run in a Node.js environment, @sentry/node will use
    // Node.js-only APIs to catch even more unhandled exceptions.
    //
    // This works well when Next.js is SSRing your page on a server with
    // Node.js, but it is not what we want when your client-side bundle is being
    // executed by a browser.
    //
    // Luckily, Next.js will call this webpack function twice, once for the
    // server and once for the client. Read more:
    // https://nextjs.org/docs#customizing-webpack-config
    //
    // So ask Webpack to replace @sentry/node imports with @sentry/browser when
    // building the browser's bundle
    if (!isServer) {
      config.resolve.alias['@sentry/node'] = '@sentry/browser';
    }

    return config;
  },
like image 178
Vadorequest Avatar answered Oct 28 '22 10:10

Vadorequest


As an alternative, you don't need to use @sentry/node. You can use @sentry/browser also. Checkout this link to see a sample implementation.

Alternatively, here you can find a well documented with-sentry option running with npx create-react-app.

like image 45
SelmanO Avatar answered Oct 28 '22 11:10

SelmanO