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

Issues with Sentry Tunnel Feature in NextJS Application (ad-blockers troubleshooting) #12035

Open
Maxalash opened this issue May 11, 2024 · 4 comments

Comments

@Maxalash
Copy link

Self-Hosted Version

24.4.2

CPU Architecture

x64

Docker Version

20.10.16

Docker Compose Version

2.6.0

Steps to Reproduce

Hello, everyone!

I'm working on integrating Sentry into my NextJS application for error tracking and monitoring. I've opted for a self-hosted Sentry setup. However, I'm encountering issues related to ad blockers that seem to interfere with Sentry's ability to capture errors correctly.

Ad blockers are blocking Sentry's error reporting requests. As a workaround, I tried to use Sentry’s “tunnel” feature, which should tunnel the requests through my server and bypass the ad blockers. Despite following the setup instructions, this doesn't seem to be working. Errors are not being logged when ad blockers are active.

Steps to reproduce:

  • Configure Sentry according to the self-hosted setup documentation.

  • Implement the tunnel feature as advised by the Sentry docs. (for DSN and sentry host name I used my own domain name)

  • Add endpoint to server-side NextJS application under custom route "/api/sentry_tunnel"

    export default async function handler(request: any, res: NextApiResponse) {
     try {
       try {
         const envelope = await request;
         const piece = envelope.body.split('\n')[0];
         if (piece?.includes('event_id')) {
           const header = JSON.parse(piece);
           const dsn = new URL(header['dsn']);
           const project_id = dsn.pathname?.replace('/', '');
           // // if (dsn.hostname !== SENTRY_HOST) {
           // //   throw new Error(`Invalid sentry hostname: ${dsn.hostname}`);
           // // }
           // // if (!project_id || !SENTRY_PROJECT_IDS.includes(project_id)) {
           // //   throw new Error(`Invalid sentry project id: ${project_id}`);
           // // }
           const upstream_sentry_url = `https://sentry.example.com/api/${project_id}/envelope/`;
           const response = await fetch(upstream_sentry_url, { method: 'POST', body: envelope.body }).catch((err) => {
             console.log('catch log', err);
           });
           return res.status(200).json({ response: response });
         }
       } catch (e) {
         console.error('error tunneling to sentry', e);
         return res.status(500).json({ error: 'error tunneling to sentry', msg: e });
       }
     } catch (error) {
       logMessage(LogLevel.ERROR, 'sentry.tunnel', error, 0, 'pages/api/sentry_tunnel.ts');
       res.status(500).json({ message: 'Error fetching data from API' });
     }
    }
  • The sentry configuration in sentry.client.config.ts, sentry.edge.config.ts, and sentry.server.config.ts

       Sentry.init({
         dsn: process.env.SENTRY_DSN,
         tunnel: process.env.SENTRY_TUNNEL + '/api/sentry_tunnel',
       });
  • Environment variable examples:

       SENTRY_URL=https://sentry.example.com/
       SENTRY_PROJECT="project-name"
       SENTRY_DSN=https://4b7102376408e9f45839b4dde8ec1ec4@o000000.ingest.sentry.example.com/2
       SENTRY_IGNORE_API_RESOLUTION_ERROR=1 
       SENTRY_TUNNEL='http://localhost:3000'
  • next.config.js configuration:

       const { withSentryConfig } = require("@sentry/nextjs");
    
       module.exports = withSentryConfig(
         module.exports,
         {
           silent: false,
           org: "sentry",
           project: JSON.stringify((localEnv || process.env).SENTRY_PROJECT),
           url: JSON.stringify((localEnv || process.env).SENTRY_URL),
         },
         {
           widenClientFileUpload: true,
           transpileClientSDK: true,
           hideSourceMaps: true,
           disableLogger: true,
           automaticVercelMonitors: true,
         }
       );
  • Run the project on the dev mode

  • Open the localhost:3000 on the Chrome browser and do some action. It works, sessions are sent to the self-hosted sentry.

  • Open the localhost:3000 on the Brave browser and do some action.

Expected Result

The session is sent to the self-hosted Sentry platform

Actual Result

The requests don't reach the sentry. However, when running come to this error in the console. I am not sure why it is still sent to sentry.io even if the sentry host and DSN are different.
Screenshot 2024-05-11 131116
The Network tab in the devtools shows that requests to the tunnel endpoint were sent successfully.
image

Event ID

No response

@Maxalash
Copy link
Author

I just noticed that there is an error in the steps section. It didn't work for the Chrome browser either. It works only if the DSN is https://[email protected]/2 and the tunnel in the Sentry.init({}) is equals to '/tunnel'. I don't know why, though. Please, can you help me clarify this? And why people put 0XXX.ingest.sentry.com? Is it important?

@hubertdeng123
Copy link
Member

I believe that adblockers and Sentry have been an issue for a while. See here for more details: #2916

@hubertdeng123
Copy link
Member

To answer your question here, I'll transfer you over to sentry-javascript as they may have more context

@hubertdeng123 hubertdeng123 transferred this issue from getsentry/self-hosted May 14, 2024
@lforst
Copy link
Member

lforst commented May 14, 2024

Hi, thanks for writing in.

  • So first of all, your environment variables will likely not get picked up in sentry.client.config.ts as long as you don't prefix them with NEXT_PUBLIC_. I recommend printing them out once to make sure they are injected into the client bundle.
  • Do not add the tunnel option to sentry.server.config.ts and sentry.edge.config.ts. Tunneling makes no sense there (unless you have a really obscure reason to do so 😂).
  • I am confused by the screenshot and the log message. If the tunnel option is set, everything should be sent to the tunnel.
  • Can you try upgrading the SDK to the latest version?
  • Also, can you share more of your logs? What do you actually send? What does Sentry respond with? Does the relay service log anything?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Status: No status
Development

No branches or pull requests

3 participants