Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@sentry/next.js 7.31 autoinstrumentation breaks middleware with named export #6815

Closed
3 tasks done
connor-baer opened this issue Jan 17, 2023 · 13 comments
Closed
3 tasks done
Labels
Package: nextjs Issues related to the Sentry Nextjs SDK Type: Bug

Comments

@connor-baer
Copy link

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which package are you using?

@sentry/nextjs

SDK Version

7.31.0

Framework Version

next@12.2.5

Link to Sentry event

No response

SDK Setup

// next.config.js

const { withSentryConfig } = require('@sentry/nextjs');

/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  sentry: {
    hideSourceMaps: false,
    autoInstrumentServerFunctions: true,
  },
};

module.exports = withSentryConfig(nextConfig);
// sentry.edge.config.ts

import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  environment: process.env.NEXT_PUBLIC_ENV,
});
// sentry.server.config.ts

import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  environment: process.env.NEXT_PUBLIC_ENV,
  integrations: [
    new Sentry.Integrations.RequestData({
      include: {
        cookies: false,
        headers: false,
        ip: false,
      },
    }),
  ],
});

Steps to Reproduce

Using the new auto instrumentation of server functions alongside the new edge SDK in @sentry/nextjs 7.31 causes the middleware to crash (see the error below) when using a named export.

Sentry is injecting code into the middleware bundle that should probably only be included in page bundles. This code fails if the middleware is exported as a named function (which is supported and suggested by the Next.js docs). In this case, there is no default export, meaning the pageComponent is undefined.

Problematic code in .next/server/src/middleware.js:

var origModule = /*#__PURE__*/Object.freeze({
    __proto__: null,
    middleware: middleware
});

/*
 * This file is a template for the code which will be substituted when our webpack loader handles non-API files in the
 * `pages/` directory.
 *
 * We use `__SENTRY_WRAPPING_TARGET_FILE__.cjs` as a placeholder for the path to the file being wrapped. Because it's not a real package,
 * this causes both TS and ESLint to complain, hence the pragma comments below.
 */

const userPageModule = origModule ;

const pageComponent = userPageModule.default;

// ⚠️ This is where the TypeError occurs: 
const origGetInitialProps = pageComponent.getInitialProps;
const origGetStaticProps = userPageModule.getStaticProps;
const origGetServerSideProps = userPageModule.getServerSideProps;

const getInitialPropsWrappers = {
  '/_app': _sentry_nextjs__WEBPACK_IMPORTED_MODULE_3__/* .wrapAppGetInitialPropsWithSentry */ .$l,
  '/_document': _sentry_nextjs__WEBPACK_IMPORTED_MODULE_3__/* .wrapDocumentGetInitialPropsWithSentry */ .B4,
  '/_error': _sentry_nextjs__WEBPACK_IMPORTED_MODULE_3__/* .wrapErrorGetInitialPropsWithSentry */ .rO,
};

const getInitialPropsWrapper = getInitialPropsWrappers['/../middleware'] || _sentry_nextjs__WEBPACK_IMPORTED_MODULE_3__/* .wrapGetInitialPropsWithSentry */ .O5;

if (typeof origGetInitialProps === 'function') {
  pageComponent.getInitialProps = getInitialPropsWrapper(origGetInitialProps) ;
}

const getStaticProps =
  typeof origGetStaticProps === 'function'
    ? _sentry_nextjs__WEBPACK_IMPORTED_MODULE_3__.wrapGetStaticPropsWithSentry(origGetStaticProps, '/../middleware')
    : undefined;
const getServerSideProps =
  typeof origGetServerSideProps === 'function'
    ? _sentry_nextjs__WEBPACK_IMPORTED_MODULE_3__.wrapGetServerSidePropsWithSentry(origGetServerSideProps, '/../middleware')
    : undefined;

Expected Result

Sentry does not inject page-related code into the middleware bundle or gracefully handles the named export of the middleware function.

Actual Result

Error [TypeError]: Cannot read properties of undefined (reading 'getInitialProps')
    at <unknown> (evalmachine.<anonymous>:113)
    at Module.4921 (evalmachine.<anonymous>:113:43)
    at __webpack_require__ (evalmachine.<anonymous>:25:43)
    at Module.3946 (evalmachine.<anonymous>:157:19)
    at __webpack_require__ (evalmachine.<anonymous>:25:43)
    at __webpack_exec__ (evalmachine.<anonymous>:306:48)
    at <unknown> (evalmachine.<anonymous>:307:53)
    at Function.__webpack_require__.O (evalmachine.<anonymous>:66:23)
    at <unknown> (evalmachine.<anonymous>:308:56)
    at webpackJsonpCallback (evalmachine.<anonymous>:176:39)
    at <unknown> (evalmachine.<anonymous>:2:61)
@connor-baer
Copy link
Author

connor-baer commented Jan 17, 2023

To be clear, there's a simple workaround: change the middleware function export to a default export.

I filed the issue since I'm sure others will run into the same problem.

@lforst
Copy link
Member

lforst commented Jan 17, 2023

Hi, thanks for writing in! A few questions:

  • Are you on windows or unix?
  • Where is your middleware file located relative to the root of the project?
  • What does your middleware file approximately look like?
  • Is the middleware file extension .ts(x)?

@connor-baer
Copy link
Author

connor-baer commented Jan 17, 2023

  • Are you on windows or unix?

I'm on unix (macOS).

  • Where is your middleware file located relative to the root of the project?

src/middleware.ts (next to the /pages folder)

  • What does your middleware file approximately look like?
import { NextRequest, NextResponse } from 'next/server';

import { Params } from 'server/services/auth/constants';
import { OIDC_COOKIES } from 'constants/cookies';

const ALLOW_LIST = [
  // Public pages
  new URLPattern({ pathname: '/:locale?/cookie-preferences' }),
  // ...
];

export function middleware(req: NextRequest): Response {
  const isAllowListed = ALLOW_LIST.some((pattern) => pattern.test(req.nextUrl));

  if (isAllowListed) {
    return NextResponse.next();
  }

  const isUnauthenticated = !req.cookies.get(OIDC_COOKIES.Token);

  if (isUnauthenticated) {
    // Middlewares run in an environment with only a subset of web APIs, therefore it is not possible to import the open-id client here.
    // Instead, redirect the user to the login API route where the necessary APIs are available.
	const rewriteUrl = req.nextUrl.clone();
  	const finalRedirectUrl = req.nextUrl.clone();

    rewriteUrl.pathname = '/api/sso/login';
    rewriteUrl.searchParams.set(Params.RedirectUrl, finalRedirectUrl.pathname);

    return NextResponse.rewrite(rewriteUrl);
  }

  return NextResponse.next();
}
  • Is the middleware file extension .ts(x)?

Yes, it's .ts.

@lforst
Copy link
Member

lforst commented Jan 17, 2023

Ok, there was an obvious oversight which we hopefully fixed. A patch will go out in an hour or so. Thanks for reporting this!

@lforst
Copy link
Member

lforst commented Jan 17, 2023

Hi, the new release is out: https://github.com/getsentry/sentry-javascript/releases/tag/7.31.1 Can you try it out and see if it resolves the issue for you? Thanks!

@connor-baer
Copy link
Author

Can confirm that this is fixed in v7.31.1. Thank you!

@lforst
Copy link
Member

lforst commented Jan 17, 2023

@connor-baer Thanks for checking!

@Sija
Copy link
Contributor

Sija commented Jan 17, 2023

I'm having similar issue with 7.31.1 on next 11.1.4.

TypeError: index_server.wrapGetStaticPropsWithSentry is not a function

Setting autoInstrumentServerFunctions: false makes it go away.
No src/middleware.js/ts present.

@lforst
Copy link
Member

lforst commented Jan 17, 2023

@Sija can you share the full error message? Thanks!

@nf-projects
Copy link

Same problem here. Seems like defining a function with export default [...] and calling it in an API route throws throws this error:

error - uncaughtException: TypeError: Cannot read properties of undefined (reading '__withSentry_applied__')
     at sentryWrappedHandler (/Users/me/project/node_modules/@sentry/nextjs/cjs/server/wrapApiHandlerWithSentry.js:70:13)
    at handler (webpack-internal:///(api)/./pages/api/auth/email-verification/requestPasswordReset.ts:41:101)
    at /Users/me/project/node_modules/@sentry/nextjs/cjs/server/wrapApiHandlerWithSentry.js:159:37
    at bound (node:domain:433:15)
    at runBound (node:domain:444:12)
    at sentryWrappedHandler (/Users/me/project/node_modules/@sentry/nextjs/cjs/server/wrapApiHandlerWithSentry.js:227:12)
    at Object.apiResolver (/Users/me/project/node_modules/next/dist/server/api-utils/node.js:363:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async DevServer.runApi (/Users/me/project/node_modules/next/dist/server/next-server.js:488:9)
    at async Object.fn (/Users/me/project/node_modules/next/dist/server/next-server.js:750:37)
    at async Router.execute (/Users/me/project/node_modules/next/dist/server/router.js:253:36)
    at async DevServer.run (/Users/me/project/node_modules/next/dist/server/base-server.js:384:29)
    at async DevServer.run (/Users/me/project/node_modules/next/dist/server/dev/next-dev-server.js:741:20)
    at async DevServer.handleRequest (/Users/me/project/node_modules/next/dist/server/base-server.js:322:20)

@lforst
Copy link
Member

lforst commented Jan 23, 2023

@nf-projects Could it be that you're manually calling an api handler in /pages/api/auth/email-verification/requestPasswordReset.ts:41:101 and not passing along req and res objects?

@a28dong
Copy link

a28dong commented Mar 7, 2023

Hi!
I think I'm experiencing a similar issue.
I tried upgrading @sentry/nextjs" to 7.41.0 and adding the sentry.edge.config.js file for middleware support, however this is causing a crash. Removing the sentry.edge.config.js file makes the crash disappear but the main reason for upgrading sentry was to have the middleware support.

TypeError: Cannot read properties of undefined (reading 'origin')
    at (../../libs/web/config/src/lib/config.ts:1:60)
    at (webpack/bootstrap:21:0)
    at (../../node_modules/next/server.js:26:18)
    at (../../node_modules/next/server.js:26:18)
    at (webpack/runtime/jsonp chunk loading:34:0)
    at (middleware:middleware.js:1:17)

@lforst
Copy link
Member

lforst commented Mar 8, 2023

@a28dong can you share more about your setup?

  • Next.js config
  • Middleware file
  • sentry.edge.config.js

Actually, it would be best if you opened a new issue. This issue is resolved.
Also please provide a reproduction example if possible. A stackblitz or similar is sufficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Package: nextjs Issues related to the Sentry Nextjs SDK Type: Bug
Projects
None yet
Development

No branches or pull requests

5 participants