NodeJS: Missing dependencies

#1

Hi everyone,

I’m trying to connect Sentry to NextJS/React app. So far I’ve successfully connected from client (React) via @sentry/browser, but if I try to connect from server-side (NextJS + Express) via @sentry/node I get an error about missing dependency:

./node_modules/@sentry/node/dist/integrations/console.js Module not found: Can't resolve 'console' in '/node_modules/@sentry/node/dist/int egrations'

As a workaround I tried to install console dependency manually but another one occured:

./node_modules/@sentry/node/dist/transports/base.js Module not found: Can't resolve 'fs' in '/node_modules/@sentry/node/dist/transpor ts'

#2

Hmm this error seems strange.

The Can't resolve 'fs' in ... error indicates that whatever you use for bundling doesn’t know about node. fs is a native module that node ships with.

So I would check your build and make sure to only use @sentry/browser for frontend (browser) stuff and @sentry/node for your server bundle.

#3

Thanks for the reply, I think you’ve brought me closer to the solution.

I am trying to connect Sentry in apollo-client via onError. This client is only called from redux-sagas triggered by action from getInitialProps - this way I’d thought that it is still server side - so I import @sentry/node which resolves into “fs” error above. If I import @sentry/browser this error pops: Sentry Logger [Error]: ReferenceError: XMLHttpRequest is not defined

1 Like
#4

Another weird thing is that if I require @sentry/node only if process.browser is false, it gives me same error as for importing @sentry/browser:
Sentry Logger [Error]: ReferenceError: XMLHttpRequest is not defined but this part of code only loads one time and it is only server-side.

1 Like
#5

Try this in custom _document.js:

import React from "react";
import Document, {
  Html,
  Head,
  Main,
  NextScript,
} from "next/document";
import { NodeClient } from "@sentry/node";

const { default: getConfig } = require("next/config");
const { publicRuntimeConfig: { sentryDSN } } = getConfig();

let sentry = null;
if (sentryDSN) {
  sentry = new NodeClient({ dsn: sentryDSN });
}

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    if (ctx.err && sentry) sentry.captureException(ctx.err);
    return { ...initialProps };
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

And this in custom _app.js:

import * as Sentry from "@sentry/browser";

const { default: getConfig } = require("next/config");
const { publicRuntimeConfig: { sentryDSN } } = getConfig();

if (sentryDSN) {
  Sentry.init({ dsn: sentryDSN });
}

It helps me.