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

Calling Sentry.flush() with @sentry/node always throws an exception on Next.js API endpoints #3748

Closed
5 of 9 tasks
Vadorequest opened this issue Jun 24, 2021 · 2 comments · Fixed by #3786 or #3811
Closed
5 of 9 tasks
Labels
Package: nextjs Issues related to the Sentry Nextjs SDK Type: Bug

Comments

@Vadorequest
Copy link

Vadorequest commented Jun 24, 2021

Package + Version

  • @sentry/browser 6.3.6
  • @sentry/node 6.3.6
  • raven-js
  • raven-node (raven for node)
  • other:

Version:

0.0.0

Description

It's recommended by Next.js to call Sentry.flush() manually, before returning an HTTP response from API endpoints.

But, it doesn't work so well. When calling the API endpoint, it doesn't send the error to Sentry and fails with [flushSafe] An exception was thrown while running Sentry.flush(). (see implementation below)

The timeout being used is 5000, which is more than what's recommended (2000).

What's also weird is that I wasn't flushing before and it was working (at least sometimes) but now it always fails.

2021-06-24T20:33:32.151Z [modules/core/amplitude/amplitudeServerClient] Logging Amplitude event "api-invoked" with properties: { apiEndpoint: 'error' }
2021-06-24T20:33:52.953Z	3751ccb9-311e-4e5d-87b1-6b1a1aa04ce9	ERROR	2021-06-24T20:33:52.397Z [api/error] Fake error - Sentry test from /api/error
2021-06-24T20:33:52.953Z	3751ccb9-311e-4e5d-87b1-6b1a1aa04ce9	ERROR	2021-06-24T20:33:35.287Z [modules/core/sentry/universal] [flushSafe] An exception was thrown while running Sentry.flush() false
import { logEvent } from '@/modules/core/amplitude/amplitudeServerClient';
import {
  AMPLITUDE_API_ENDPOINTS,
  AMPLITUDE_EVENTS,
} from '@/modules/core/amplitude/events';
import { createLogger } from '@/modules/core/logging/logger';
import { configureReq } from '@/modules/core/sentry/server';
import { flushSafe } from '@/modules/core/sentry/universal';
import * as Sentry from '@sentry/node';
import {
  NextApiRequest,
  NextApiResponse,
} from 'next';

const fileLabel = 'api/error';
const logger = createLogger({
  fileLabel,
});

/**
 * Error endpoint - Throws an error upon being called.
 *
 * Mock API endpoint whose sole purpose is to throw an error, nothing else.
 * Meant to be used to check whether monitoring (Sentry) works as expected.
 *
 * @param req
 * @param res
 * @method GET
 */
export const error = async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {
  try {
    configureReq(req, { fileLabel });

    await logEvent(AMPLITUDE_EVENTS.API_INVOKED, null, {
      apiEndpoint: AMPLITUDE_API_ENDPOINTS.ERROR,
    });

    throw Error('Fake error - Sentry test from /api/error');
  } catch (e) {
    Sentry.captureException(e);
    logger.error(e.message);

    await flushSafe();

    res.json({
      error: true,
      message: process.env.NEXT_PUBLIC_APP_STAGE === 'production' ? undefined : e.message,
    });
  }
};

/**
 * Flushes Sentry queue in a safe way.
 *
 * It's necessary to flush all Sentry events on the server, because Vercel runs on AWS Lambda, see https://vercel.com/docs/platform/limits#streaming-responses
 * If you don't flush, then it's possible the Sentry events won't be sent.
 * This helper is meant to be used for backend-only usage. (not frontend)
 *
 * There is a potential bug in Sentry that throws an exception when flushing times out, causing API endpoints to fail.
 * @see https://github.com/getsentry/sentry/issues/26870
 */
export const flushSafe = async (): Promise<boolean> => {
  try {
    return await Sentry.flush(FLUSH_TIMEOUT);
  } catch (e) {
    logger.error(`[flushSafe] An exception was thrown while running Sentry.flush()`, e);
    return false;
  }
};

export default error;

image

@Vadorequest
Copy link
Author

The reason behind this behavior is because Sentry.init() wasn't called and no SENTRY_DSN was provided.

When providing SENTRY_DSN, this error goes away.

The behaviour when SENTRY_DSN isn't defined is really confusing and misleading.

@lobsterkatie
Copy link
Member

Hi, @Vadorequest.

Once 6.10.0 is released (hopefully tomorrow), can you please give this another try? Two separate problems were causing this, I believe - one related to the SDK not starting up, and one related to flush (which withSentry calls), and they have hopefully been resolved here and here.

I'm going to close this, but please reach out if you're still having trouble.

Thanks!

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
3 participants