9

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

Danila
  • 15,606
  • 2
  • 35
  • 67
LiranC
  • 2,400
  • 1
  • 27
  • 55
  • I'm facing exactly the same issue, but my setup doesn't include Next.js or AMP, just a React app with a separate Node.js server. – Timo Jan 17 '20 at 10:13

3 Answers3

3

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:

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;
  },
Vadorequest
  • 16,593
  • 24
  • 118
  • 215
2

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.

SelmanO
  • 21
  • 3
0

Make sure that you call the function after requiring it...

const withSourceMaps = require('@zeit/next-source-maps')();
                                                        ^^

I had the same issue and that fixed it for me.