Javascript: Uploading attachment gets 201 but I don't see attachment

I am using Expo - Using Sentry - Expo Documentation

In my development environment I get a 201 status code on upload of attachment, but I don’t see the attachment on the event. I am paying customer, $30/month, so I don’t think it’s hitting quotas.

Whenever the “extra” of “myAttachment” is there, I want to JSON.stringify that and upload it with this code.

This is how I add myAttachment to extras:

import * as Sentry from 'sentry-expo';

Sentry.Native.withScope(scope => {

    scope.setExtras({
      myAttachment: {
        testingMessage: 'hi there'
      }
    });

    // Sentry.Native.captureException(new Error('this should have it attached'));
    Sentry.Native.captureMessage('this should have it attached');
});

And this is my upload code, it gives status code of 201 but I don’t see it.

Note in production, it gives “TypeError: Network request failed” - I have no idea why but I’ll save this question for later.

Sentry.init({...});

Sentry.Browser.addGlobalEventProcessor(event => {
  if (event?.extra?.myAttachment) {
    try {
      const myAttachment = event.extra.myAttachment;
      delete event.extra.myAttachment;

      const client = Sentry.Browser.getCurrentHub().getClient();
      if (!client) {
        console.error(
          new Error('No client available.'),
          'sentry.uploadMyAttachment'
        );
        return event;
      }

      const dsn = client.getDsn();
      if (!dsn) {
        console.error(
          new Error('No client DSN available.'),
          'sentry.uploadMyAttachment'
        );
        return event;
      }

      if (!event.event_id) {
        console.error(
          new Error('No event_id available.'),
          'sentry.uploadMyAttachment'
        );
        return event;
      }

      const endpoint = attachmentUrlFromDsn(dsn, event.event_id);

      const formData = new FormData();
      formData.append(
        'my-attachment',
        new Blob([JSON.stringify(myAttachment)], {
          type: 'application/json'
        }),
        'myAttachment.json'
      );

      fetch(endpoint, { method: 'POST', body: formData })
        .then(async res => {
          console.log('has myAttachment response!', {
            status: res.status,
            text: await res.text()
          });
        })
        // we have to catch this otherwise it throws an infinite loop in Sentry
        .catch(error => {
          console.error(error, 'sentry.uploadMyAttachment.fetch');
        });
    } catch (error) {
      console.error(error, 'sentry.uploadMyAttachment');
    }
  }

  return event;
});


function attachmentUrlFromDsn(dsn, eventId) {
  const { host, path, projectId, port, protocol, user } = dsn;
  return `${protocol}://${host}${port !== '' ? `:${port}` : ''}${
    path !== '' ? `/${path}` : ''
  }/api/${projectId}/events/${eventId}/attachments/?sentry_key=${user}&sentry_version=7&sentry_client=custom-javascript`;
}

I’m getting the same thing. Did you figure this out?

I finally got this by using react-native-blob-util:

import * as Sentry from '@sentry/react-native'
import RNBlob from 'react-native-blob-util'
import { Event, Dsn } from '@sentry/types'

const { dirs, exists } = RNBlob.fs
const DocsPath = dirs.DocumentDir

export function attachmentUrlFromDsn(dsn: Dsn, eventId: string) {
  const { host, path, projectId, port, protocol, user } = dsn
  return `${protocol}://${host}${port !== '' ? `:${port}` : ''}${
    path !== '' ? `/${path}` : ''
  }/api/${projectId}/events/${eventId}/attachments/?sentry_key=${user}&sentry_version=7&sentry_client=custom-javascript`
}

Sentry.addGlobalEventProcessor(async (event: Event) => {
  try {
    const logPath = `${DocsPath}/unity-log.txt`
    if (!(await exists(logPath))) {
      // console.log('[Sentry] Unity log is empty')
      return
    }
    const client = Sentry.getCurrentHub().getClient()
    const endpoint = attachmentUrlFromDsn(client.getDsn(), event.event_id)
    // console.log(`[Sentry] POST: ${endpoint}`)
    await RNBlob.fetch(
      'POST',
      endpoint,
      {},
      [
        { name: 'type', data: 'text/plain' },
        { name: 'my-attachment', filename: 'unity-log.txt', data: RNBlob.wrap(logPath) },
      ],
    )
    return event
  } catch (ex) {
    console.error('[Sentry] Error when trying to attach Unity log', ex)
  }
})
1 Like

I was in touch with the support team and they said they are working on it, but it hasn’t come out yet :frowning: