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/nextjs not reporting errors in next.js api routes #6450

Closed
Jay-flow opened this issue Dec 7, 2022 · 24 comments
Closed

@sentry/nextjs not reporting errors in next.js api routes #6450

Jay-flow opened this issue Dec 7, 2022 · 24 comments
Labels

Comments

@Jay-flow
Copy link

Jay-flow commented Dec 7, 2022

Version

@sentry/nextjs: 7.23.0
next: 13.0.6

Issue

@sentry/nextjs not reporting errors in next.js api routes
Only errors from the font-end are reported to Sentry.

Do not report API errors to Sentry.

pages/api/test.ts

import { withSentry } from "@sentry/nextjs"
import { OK } from "http-status"
import { NextApiRequest, NextApiResponse } from "next"

const handle = async (req: NextApiRequest, res: NextApiResponse) => {
  throw new Error("API Test 1")

  return res.status(OK).end()
}

export default withSentry(handle)

I completed the setting according to the guide.

Below are the files I set up.
sentry.client.config.ts

import * as Sentry from "@sentry/nextjs"

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tracesSampleRate: 1.0,
})

sentry.server.config.ts

import * as Sentry from "@sentry/nextjs"

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tracesSampleRate: 1.0,
  debug: true,
})

next.config.js

/** @type {import('next').NextConfig} */
const { withSentryConfig } = require("@sentry/nextjs")

const securityHeaders = [
  {
    key: "X-XSS-Protection",
    value: "1; mode=block",
  },
]

const nextConfig = {
  reactStrictMode: false,
  sentry: {
    hideSourceMaps: true,
  },
  webpack: (config) => {
    if (!config.experiments) {
      config.experiments = {}
    }

    config.experiments.topLevelAwait = true
    config.resolve.fallback = {
      ...config.resolve.fallback,
      fs: false,
    }

    return config
  },
 async headers() {
    return [
      {
        source: "/:path*",
        headers: securityHeaders,
      },
    ]
  },
}

module.exports = withSentryConfig(nextConfig, {
  // silent: true,
})

pages/_error.tsx

/**
 * NOTE: This requires `@sentry/nextjs` version 7.3.0 or higher.
 *
 * This page is loaded by Nextjs:
 *  - on the server, when data-fetching methods throw or reject
 *  - on the client, when `getInitialProps` throws or rejects
 *  - on the client, when a React lifecycle method throws or rejects, and it's
 *    caught by the built-in Nextjs error boundary
 *
 * See:
 *  - https://nextjs.org/docs/basic-features/data-fetching/overview
 *  - https://nextjs.org/docs/api-reference/data-fetching/get-initial-props
 *  - https://reactjs.org/docs/error-boundaries.html
 */

import * as Sentry from "@sentry/nextjs"
import type { NextPage } from "next"
import type { ErrorProps } from "next/error"
import NextErrorComponent from "next/error"

const CustomErrorComponent: NextPage<ErrorProps> = (props) => {
  // If you're using a Nextjs version prior to 12.2.1, uncomment this to
  // compensate for https://github.com/vercel/next.js/issues/8592
  // Sentry.captureUnderscoreErrorException(props);

  return <NextErrorComponent statusCode={props.statusCode} />
}

CustomErrorComponent.getInitialProps = async (contextData) => {
  // In case this is running in a serverless function, await this in order to give Sentry
  // time to send the error before the lambda exits
  await Sentry.captureUnderscoreErrorException(contextData)

  // This will contain the status code of the response
  return NextErrorComponent.getInitialProps(contextData)
}

export default CustomErrorComponent

.sentryclirc

[auth]
token=xxxxxxxxxxxxxxx

sentry.prooperties

defaults.url=https://sentry.io/
defaults.org=xxxx
defaults.project=javascript-nextjs
cli.executable=node_modules/@sentry/cli/bin/sentry-cli

Below is the log displayed on the console.

info  - @sentry/nextjs is running with the autoInstrumentServerFunctions flag set, which means API routes no longer need to be manually wrapped with withSentry. Detected manual wrapping in /api/test.
wait  - compiling /_error (client and server)...
error - pages/api/test.ts (6:8) @ handle
error - Error: API Test 1
    at handle (webpack-internal:///(api)/./pages/api/test.ts?__sentry_wrapped__:12:11)
    at sentryWrappedHandler (/Users/asdf/Projects/test-web/node_modules/@sentry/nextjs/cjs/config/wrappers/withSentryAPI.js:62:14)
    at /Users/asdfProjects/test-web/node_modules/@sentry/nextjs/cjs/config/wrappers/withSentryAPI.js:132:37
    at bound (node:domain:433:15)
    at runBound (node:domain:444:12)
    at sentryWrappedHandler (/Users/asdf/Projects/test-web/node_modules/@sentry/nextjs/cjs/config/wrappers/withSentryAPI.js:196:12)
    at Object.apiResolver (/Users/asdf/Projects/test-web/node_modules/next/dist/server/api-utils/node.js:363:15)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async DevServer.runApi (/Users/asdf/Projects/test-web/node_modules/next/dist/server/next-server.js:474:9) {
  page: '/api/test'
}
  4 | 
  5 | const handle = async (req: NextApiRequest, res: NextApiResponse) => {
> 6 |   throw new Error("API Test 1")
    |        ^
  7 | 
  8 |   return res.status(OK).end()
  9 | }
[Sentry Webpack Plugin] Creating new release:
 'development'
[Sentry Webpack Plugin] Calling upload-sourcemaps with:
 {
  finalize: true,
  rewrite: true,
  include: [
    {
      paths: [
        '/Users/asdf/Projects/test-web/.next/static/chunks/pages'
      ],
      urlPrefix: '~/_next/static/chunks/pages'
    }
  ],
  ignore: [],
  configFile: 'sentry.properties',
  stripPrefix: [ 'webpack://_N_E/' ],
  urlPrefix: '~/_next',
  entries: [Function: entries],
  release: 'development',
  dryRun: true
}
[Sentry Webpack Plugin] Finalizing release:
 'development'
[Sentry Webpack Plugin] Creating new release:
 'development'
[Sentry Webpack Plugin] Calling upload-sourcemaps with:
 {
  finalize: true,
  rewrite: true,
  include: [
    {
      paths: [ '/Users/asdf/Projects/test-web/.next/server/pages/' ],
      urlPrefix: '~/_next/server/pages'
    },
    {
      paths: [ '/Users/asdf/Projects/test-web/.next/server/chunks/' ],
      urlPrefix: '~/_next/server/chunks'
    }
  ],
  ignore: [],
  configFile: 'sentry.properties',
  stripPrefix: [ 'webpack://_N_E/' ],
  urlPrefix: '~/_next',
  entries: [Function: entries],
  release: 'development',
  dryRun: true
}
[Sentry Webpack Plugin] Finalizing release:
 'development'
event - compiled client and server successfully in 538 ms (1680 modules)

Expected Result

@sentry/nextjs should be reported to Sentry about API errors.

Actual Result

@sentry/nextjs not reporting errors in next.js api routes

Related Issues

#3917

@lforst
Copy link
Member

lforst commented Dec 7, 2022

Hi, are the logs you shared from running next build or next start or next dev? We're not guaranteeing to report errors that happen during build.

@lforst lforst added Package: nextjs Issues related to the Sentry Nextjs SDK and removed Status: Untriaged labels Dec 7, 2022
@lforst
Copy link
Member

lforst commented Dec 7, 2022

Also, can you share the logs with debug: true in sentry.server.config.ts? Thank you.

@Jay-flow
Copy link
Author

Jay-flow commented Dec 7, 2022

@lforst
I learned something from a few tests.
When the command below is executed sequentially, it normally reports API errors to Sentry.

  1. yarn build
  2. yarn start

In other words, if I run Next.js after building, error reporting works normally.

However, when I run the development mode with the yarn dev command, it doesn't report API errors.
The difference occurs when no code has been changed and only the command being executed is different.

My scripts

"scripts": {
    "dev": "next dev",
    "build": "tsc --noEmit && next build",
    "start": "next start",
 }

the logs with debug: true in sentry.server.config.ts

ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info  - Loaded env from /Users/asdf/Projects/test-web/.env
Sentry Logger [log]: Initializing SDK...
Sentry Logger [log]: Integration installed: InboundFilters
Sentry Logger [log]: Integration installed: FunctionToString
Sentry Logger [log]: Integration installed: Console
Sentry Logger [log]: Integration installed: Http
Sentry Logger [log]: Integration installed: OnUncaughtException
Sentry Logger [log]: Integration installed: OnUnhandledRejection
Sentry Logger [log]: Integration installed: ContextLines
Sentry Logger [log]: Integration installed: Context
Sentry Logger [log]: Integration installed: Modules
Sentry Logger [log]: Integration installed: RequestData
Sentry Logger [log]: Integration installed: LinkedErrors
Sentry Logger [log]: Integration installed: RewriteFrames
Sentry Logger [log]: SDK successfully initialized
Sentry Logger [log]: [Tracing] Continuing trace dda07f49f5394bff9eaa9319f883b055.
Sentry Logger [log]: [Tracing] starting http.server transaction - GET /api/auth/[...nextauth]
Sentry Logger [log]: [Tracing] Finishing http.server transaction: GET /api/auth/[...nextauth].
Sentry Logger [log]: Flushing events...
Sentry Logger [log]: Done flushing events
Sentry Logger [log]: [Tracing] starting http.server transaction - GET /api/test
info  - @sentry/nextjs is running with the autoInstrumentServerFunctions flag set, which means API routes no longer need to be manually wrapped with withSentry. Detected manual wrapping in /api/test.
Sentry Logger [log]: [Tracing] starting http.server transaction - GET /api/test
Sentry Logger [log]: [Tracing] Finishing http.server transaction: GET /api/test.
Sentry Logger [log]: Flushing events...
Sentry Logger [log]: Done flushing events
Error: API TEST
    at handle (/Users/asdf/Projects/test-web/.next/server/pages/api/test.js:76:11)
    at sentryWrappedHandler (/Users/asdf/Projects/test-web/node_modules/@sentry/nextjs/cjs/config/wrappers/withSentryAPI.js:62:14)
    at /Users/asdf/Projects/test-web/node_modules/@sentry/nextjs/cjs/config/wrappers/withSentryAPI.js:132:37
    at bound (node:domain:433:15)
    at runBound (node:domain:444:12)
    at sentryWrappedHandler (/Users/asdf/Projects/test-web/node_modules/@sentry/nextjs/cjs/config/wrappers/withSentryAPI.js:196:12)
    at Object.apiResolver (/Users/jasdf/Projects/test-web/node_modules/next/dist/server/api-utils/node.js:363:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async NextNodeServer.runApi (/Users/asdf/Projects/test-web/node_modules/next/dist/server/next-server.js:474:9)
    at async Object.fn (/Users/asdfProjects/test-web/node_modules/next/dist/server/next-server.js:736:37)
Sentry Logger [log]: Flushing events...
Sentry Logger [log]: Done flushing events
Sentry Logger [log]: [Tracing] starting http.server transaction - GET /api/auth/session
Sentry Logger [log]: [Tracing] starting http.server transaction - GET /api/auth/[...nextauth]
Sentry Logger [log]: [Tracing] Finishing http.server transaction: GET /api/auth/[...nextauth].
Sentry Logger [log]: Flushing events...
Sentry Logger [log]: Done flushing events

@lforst
Copy link
Member

lforst commented Dec 8, 2022

Ok, I think I can somewhat reproduce this. I will put this on our backlog but just as a quick disclaimer fixing this is not gonna have a high priority. Dev mode is super sketchy in Next.js/Webpack and our priority is clearly in getting production builds to work smoothly. Thank you for surfacing this though!

If you want to debug your Sentry SDK configuration I recommend just doing a production build locally.

@wscotten
Copy link

wscotten commented Jul 13, 2023

Bump. Seems like Nextjs api route handlers are still not supported automatically with Sentry. This would be a very nice nice-to-have 😄.

@lforst
Copy link
Member

lforst commented Jul 24, 2023

@wscotten the issue you want to follow is likely this one: #7228.

We already started implementing support but the app router was still constantly changing and we didn't wanna do work twice (or even thrice) so we delayed it a bit until Next.js gets more stable again.

@popuguytheparrot
Copy link

I Have same issue, API routes dont handle and sentry.edge.config.ts dont call init

@Stefandasbach
Copy link

What's the update on this @AbhiPrasad and @lforst? Actively blocking so will have to go with a solution like Highlight if this isn't going to be tackled by the team

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 Aug 14, 2023
@AbhiPrasad
Copy link
Member

AbhiPrasad commented Aug 14, 2023

@Stefandasbach I assume you are talking about Next 13 app dir API routes right? #7228

The solution here is nontrivial, and we need to make sure that it is stable between versions considering there is no exposed error handler by the next.js framework we can hook into.

Some of the complexity comes from:

  1. handling node vs. edge runtime
  2. handling Vercel vs. non-vercel environments (deploying on vercel causes different API route behaviour)
  3. supporting different permutations of Next.js versions (since there are significant internal differences between Next.js minors)
  4. making sure autowrapping does not break cache revalidation and redirects (there are multiple caches that next.js relies on under the hood, see Next.js cache docs for more details)

For now you can manually wrap your API routes in a try-catch and using Sentry that way! I don't think anyone else offers an alternate solution to this right? I can't find another error monitoring solution that supports auto-wrapping nextjs 13 app dir API routes - but please correct me if I'm wrong.

I'm going to try to get this bumped up in priority for the team! Thanks for your patience.

@PineSpire
Copy link

PineSpire commented Aug 14, 2023 via email

@Stefandasbach
Copy link

Hey @AbhiPrasad, appreciate the thoughtful response and insight.

I'm going to try to get this bumped up in priority for the team! Thanks for your patience.
Looking forward to hearing the progress, and happy to help test if it's helpful.

For now you can manually wrap your API routes in a try-catch and using Sentry that way! I don't think anyone else offers an alternate solution to this right?
I'll give this a shot. Thanks for the idea.

I can't find another error monitoring solution that supports auto-wrapping nextjs 13 app dir API routes - but please correct me if I'm wrong.
Highlight uses this hook for instantiation in Nextjs 13 App Directory.

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 Aug 20, 2023
@lforst
Copy link
Member

lforst commented Aug 21, 2023

Highlight uses this hook for instantiation in Nextjs 13 App Directory.

@Stefandasbach While it is cool that the Next.js team added this hook, it does not meet our standards/requirements for instrumentation. Since we need more powerful instrumentation mechanisms to support features like distributed tracing and error and performance monitoring for individual routes/server components, as well as request context isolation we had to build our own webpack processing pipeline in order to properly instrument everything. This is where a lot of the complexity and development efforts come from.

In the meanwhile, we started working on the route handlers for the app router. You can track the progress here: #8832

@samipshah100
Copy link

i have the same use case
will doing something like this send the error manually to sentry?

 } catch (e) {
    console.log('error occured in getSectionStreamViaEdge ', e);
    Sentry.captureMessage('Something went wrong');
  }

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 Aug 22, 2023
@lforst
Copy link
Member

lforst commented Aug 23, 2023

@samipshah100 Yes, that should work for basic error monitoring functionality. (Note that it is not as simple as that so some things may get funky - like bleeding transaction information, bleeding breadcrumbs, weird tags and stuff like that)

@AbhiPrasad
Copy link
Member

@Stefandasbach #8832 merging in should solve the majority of concerns here and means you don't have to set up an instrumentation.ts file or wrap anything with a wrapper function - auto-instrumented out of the box.

@lforst
Copy link
Member

lforst commented Sep 5, 2023

@Jay-flow sorry this issue got a bit messy because people misunderstood it. Are you still facing this problem in the newest version of the SDK?

@getsantry getsantry bot moved this to Waiting for: Community in GitHub Issues with 👀 Sep 5, 2023
@getsantry
Copy link

getsantry bot commented Sep 27, 2023

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you remove the label Waiting for: Community, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

@getsantry getsantry bot added the Stale label Sep 27, 2023
@getsantry getsantry bot closed this as completed Oct 5, 2023
@tomelliot
Copy link

tomelliot commented Oct 22, 2023

Edit: My own fault. Resolution here: #6450 (comment)

Responding here, but let me know if you'd rather I create a new issue.

I'm not seeing my API endpoints getting auto instrumented.
@sentry/[email protected]
[email protected]

I was using a prior version of sentry and updated to take advantage of this improved autoinstrumentation.
I haven't been able to get it working. I just ran through the install wizard again to see if that helped. Still not seeing anything reported back to Sentry when an API endpoint throws an error.

I've set debug: true in my Sentry.init({}) and I'm seeing the Sentry Logger report to the server console (not browser console) when I load a page in the browser. When I curl an endpoint that throws an error, I'm not seeing anything from Sentry, just the error being printed to the console.

Two things that could be causing issues:

  1. I'm using next-compose-plugins to include other plugins:
// next.config.js
...

const other_configs = withPlugins([withBundleAnalyzer({})], nextConfig);
const { withSentryConfig } = require("@sentry/nextjs");
module.exports = withSentryConfig(
  other_configs,
  {...},
  {...})
  1. I'm using Route Groups so I have several folders under my app folder:
  • /api/
  • /(web)/
  • /(app)/

Any help is appreciated!

// sentry.server.config.ts

import * as Sentry from "@sentry/nextjs";
Sentry.init({
  dsn: "...",
  tracesSampleRate: 1,
  debug: true,
});

@lforst
Copy link
Member

lforst commented Oct 23, 2023

@tomelliot Yes, would you mind creating a new issue for this? Thank you!

@tomelliot
Copy link

@lforst In trying to create a reproduction I found this was my own fault:

I was mistakenly using route.tsx instead of route.ts for some endpoints. Next.js doesn't complain about this, but Sentry wasn't instrumenting them. I've made a suggestion on the Next.js github for them to warn for this at build time. I'm not sure how it would fit with Sentry's process, but as a Sentry user, if Sentry caught un-instrumented routes and told me about it that'd be a great nice-to-have feature.

@lforst
Copy link
Member

lforst commented Oct 23, 2023

@tomelliot Awesome. Thanks for raising something upstream! I am wondering, are the API routes working at all if it is .tsx? If so, we should change the SDK to also instrument those files. I remember last time I checked, Next.js didn't allow route.tsx.

@tomelliot
Copy link

tomelliot commented Oct 23, 2023

@lforst Yeah the misnamed endpoints seemed to be working fine - I had no reason to realise there was a problem.

Maybe something to shake out with the Next.js team - are .tsx files meant to work or not. If they're not then it sounds like something they might want to update.

@lforst
Copy link
Member

lforst commented Oct 23, 2023

Their docs say only .js and .ts. I'll chime in in the discussion you opened!

Screenshot 2023-10-23 at 12 31 07

https://nextjs.org/docs/app/building-your-application/routing/route-handlers#convention

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
Development

No branches or pull requests

10 participants