Skip to content

Replay data isn't available to tunnel middleware if Sentry tunnel is enabled #562

Description

@ryan-cahill

Version

@nuxtjs/sentry: 7.2.1
nuxt: 2.16.1

Sentry configuration

publicRuntimeConfig: {
  ...
      sentry: {
        config: {
          dsn: '<removed>',
          ...
        },
        clientConfig: {
          tunnel: '/tunnel/sentry',
        },
      },
    },
...
    sentry: {
      dsn: '<removed>',
      clientConfig: {
        replaysSessionSampleRate: process.env.ENVIRONMENT === 'local' ? 1.0 : 0.1,
        replaysOnErrorSampleRate: 1.0,
      },
      clientIntegrations: {
        Replay: {},
      },
    },
    ....
    serverMiddleware: [
      { path: '/tunnel/sentry', handler: 'server-middleware/sentry.tunnel.ts' },
    ]
    ...
  ...

Sentry server middleware

// src/server-middleware/sentry.tunnel.ts

import axios from 'axios';
import express from 'express';

// https://github.com/getsentry/examples/blob/a9f50106988ce2d21e41ab8584ebaccef4988709/tunneling/nextjs/pages/api/tunnel.js

// Change host appropriately if you run your own Sentry instance.
const sentryHost = '.sentry.io';

// Set knownProjectIds to an array with your Sentry project IDs which you
// want to accept through this proxy.
const knownProjectIds = ['<removed>'];

const middleware = express();

middleware.use(express.text({ limit: '50mb' }));

middleware.all('/', async (req, res) => {
  try {
    const envelope = req.body;

    const pieces = envelope.split('\n');

    const header = JSON.parse(pieces[0]);

    const { host, pathname } = new URL(header.dsn);
    if (!host.endsWith(sentryHost)) {
      throw new Error(`invalid host: ${host}`);
    }

    const projectId = pathname.slice(1);
    if (!knownProjectIds.includes(projectId)) {
      throw new Error(`invalid project id: ${projectId}`);
    }

    const url = `https://${host}/api/${projectId}/envelope/`;
    const response = await axios.post(url, envelope, { timeout: 10000 });
    res.end(JSON.stringify(response.data));
  } catch (e) {
    console.error(e);
    res.statusCode = 400;
    res.end(JSON.stringify({ status: 'invalid request' }));
  }
});

export default middleware;

Steps to reproduce

  • Add server middleware to handle Sentry requests such src/server-middleware/sentry.tunnel.ts above
  • Update Sentry configuration to the settings above
  • Start application
  • Throw a new error anywhere in an application mounted() function in order to trigger a Sentry error
  • Notice that in the middleware, req.body is just an empty object

What is Expected?

There should be some kind of data representing the replay event in req.body in the tunnel middleware to forward to Sentry

What is actually happening?

req.body is just an empty object in the tunnel middleware, so there's no replay data to forward to Sentry

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions