Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to setup Sentry-cli source maps with react-native

Introduction

Hi, I'm trying to get Sentry to recognise our sourcemaps in a react-native project, but I can't get it working.

The artifacts are uploading - I can see them in the WebUI, but the events lack context/mapping:

Question

Can anyone see any problems in my setup?

Thanks!

 Background

Assumptions

  • uploading release artifacts, then deleting artifacts from web ui, then re-uploading new artifacts is valid
  • "abs_path": "app:///index.bundle", requires the bundled js needs to be renamed to index.bundle
  • That fact that all events have a processing error: Discarded invalid parameter 'dist' should not effect sourcemaps
  • Once everything lines up, all my historical events for the release will benefit from the uploaded files/sourcemaps

Xcode build phase

During the XCode build phase we already bundle the DSym.

In this script, I'm trying to pull out the bundled js and sourcemap, and uploading it.

Script

#!/bin/bash
# WARNING: Run directly from Xcode

# For testing of Xcode bundling/sentry locally, set to "true"
DEBUG_FORCE_BUNDLING="true"

printf "Xcode: Bundle react-native and upload to Sentry"

source ../scripts/xcode/utils/node_activate.sh

# Create bundle and sourcemap
export NODE_BINARY=node
export SENTRY_PROPERTIES=sentry.properties
DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH
export EXTRA_PACKAGER_ARGS="--sourcemap-output $DEST/main.bundle.map.js";
if [ "${CONFIGURATION}" = "Release" ]; then
    FORCE_BUNDLING="$DEBUG_FORCE_BUNDLING" \
    ../node_modules/@sentry/cli/sentry-cli react-native xcode \
    ../node_modules/react-native/scripts/react-native-xcode.sh
else
   FORCE_BUNDLING="$DEBUG_FORCE_BUNDLING" \
   ../node_modules/@sentry/cli/sentry-cli react-native xcode \
   ../node_modules/react-native/scripts/react-native-xcode.sh
fi

# Copy bundle & sourcemap
mkdir -p ../.xcodebuild
cp $DEST/main.jsbundle ../.xcodebuild/index.bundle # rename?
cp $DEST/main.bundle.map.js ../.xcodebuild
echo "Size of file $(wc -c ../.xcodebuild/index.bundle)" # RENAME!?
echo "Size of sourcemap $(wc -c ../.xcodebuild/main.bundle.map.js)"

# Upload sentry release
# https://docs.sentry.io/cli/releases/#creating-releases
APP_IDENTIFIER="com.mycompany.app"
VERSION="1.4.21"
RELEASE_NAME="$APP_IDENTIFIER-$VERSION"
DISTRIBUTION_NAME="2400"

function sentry_release {
    npx sentry-cli releases \
        files $RELEASE_NAME \
        $1 $2 $3
        --dist $DISTRIBUTION_NAME \
        --strip-prefix ".build" \
        --ignore node_modules \
        --rewrite "$(pwd)"

}

sentry_release upload ../.xcodebuild/index.bundle '~/index.bundle'
echo "sentry_release upload"

sentry_release upload-sourcemaps ../.xcodebuild/main.bundle.map.js
echo "sentry_release upload-sourcemaps"

echo `date`
echo "DONE"

Note: The important bit of node_modules/react-native/scripts/react-native-xcode.sh is:

BUNDLE_FILE="$DEST/main.jsbundle"

echo "BUNDLE_FILE: $BUNDLE_FILE" > ~/bh/react-native-native/bundle.log

"$NODE_BINARY" $NODE_ARGS "$CLI_PATH" $BUNDLE_COMMAND \
  $CONFIG_ARG \
  --entry-file "$ENTRY_FILE" \
  --platform ios \
  --dev $DEV \
  --reset-cache \
  --bundle-output "$BUNDLE_FILE" \
  --assets-dest "$DEST" \
  $EXTRA_PACKAGER_ARGS

Script output

Xcode: Upload Debug Symbols to SentryNow using node v11.11.0 (npm v6.7.0)
FORCE_BUNDLING enabled; continuing to bundle.
warning: the transform cache was reset.
Loading dependency graph, done.
info Writing bundle output to:, /Users/me/Library/Developer/Xcode/DerivedData/TheApp-cvfhlrosjrphnjdcngyqxnlmjjbb/Build/Products/Debug-iphonesimulator/TheApp.app/main.jsbundle
info Writing sourcemap output to:, /Users/me/Library/Developer/Xcode/DerivedData/TheApp-cvfhlrosjrphnjdcngyqxnlmjjbb/Build/Products/Debug-iphonesimulator/TheApp.app/main.bundle.map.js
info Done writing bundle output
info Done writing sourcemap output
info Copying 109 asset files
info Done copying assets
Size of file  8477623 ../.xcodebuild/index.bundle
Size of sourcemap  15378754 ../.xcodebuild/main.bundle.map.js
A 560eaee15f0c1ccb5a57b68b5dc1b4944cff84d2  (8477623 bytes)
sentry_release upload
> Analyzing 1 sources
> Adding source map references
> Uploading source maps for release com.mycompany.app-1.4.21

Source Map Upload Report
  Source Maps
    ~/main.bundle.map.js
sentry_release upload-sourcemaps
Fri May 3 15:50:26 BST 2019
DONE

Sentry event JSON

Trimmed some breadcrumbs/callstack:

// 20190503154011
// https://sentry.mycompany.com/mycompany/react-native-app/issues/4205/events/396945/json/

{
  "id": "1c754ed7d651445eb48ed79c995073e2",
  "project": 11,
  "release": "com.mycompany.app-1.4.21",
  "platform": "cocoa",
  "culprit": "crash(app:///index.bundle)",
  "message": "Error Sentry: TEST crash crash(app:///index.bundle)",
  "datetime": "2019-05-03T14:32:25.000000Z",
  "time_spent": null,
  "tags": [
    [
      "logger",
      "javascript"
    ],
    [
      "sentry:user",
      "id:b5f212b4-9112-4253-86cc-11583ac1945a"
    ],
    [
      "sentry:release",
      "com.mycompany.app-1.4.21"
    ],
    [
      "level",
      "fatal"
    ],
    [
      "device",
      "iPhone9,1"
    ],
    [
      "device.family",
      "iOS"
    ],
    [
      "os",
      "iOS 12.1"
    ],
    [
      "os.name",
      "iOS"
    ],
    [
      "os.rooted",
      "no"
    ]
  ],
  "contexts": {
    "device": {
      "model_id": "simulator",
      "family": "iOS",
      "simulator": true,
      "type": "device",
      "storage_size": 499963170816,
      "free_memory": 274915328,
      "memory_size": 17179869184,
      "boot_time": "2019-04-29T07:53:06Z",
      "timezone": "GMT+1",
      "model": "iPhone9,1",
      "usable_memory": 16463810560,
      "arch": "x86"
    },
    "app": {
      "app_version": "1.4.21",
      "app_name": "MyApp",
      "device_app_hash": "<device_app_hash>",
      "app_id": "<app_id>",
      "app_build": "2400",
      "app_start_time": "2019-05-03T14:31:33Z",
      "app_identifier": "com.mycompany.app",
      "type": "default",
      "build_type": "simulator"
    },
    "os": {
      "rooted": false,
      "kernel_version": "Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64",
      "version": "12.1",
      "build": "17G65",
      "type": "os",
      "name": "iOS"
    }
  },
  "errors": [
    {
      "type": "invalid_attribute",
      "name": "dist"
    }
  ],
  "extra": {
    "session:duration": 52129
  },
  "fingerprint": [
    "{{ default }}"
  ],
  "metadata": {
    "type": "Error",
    "value": "Sentry: TEST crash"
  },
  "received": 1556893946.0,
  "sdk": {
    "client_ip": "109.69.86.251",
    "version": "0.42.0",
    "name": "sentry.javascript.react-native"
  },
  "sentry.interfaces.Breadcrumbs": {
    "values": [
      {
        "category": "console",
        "timestamp": 1556893700.0,
        "message": "%c prev state color: #9E9E9E; font-weight: bold [object Object]",
        "type": "default"
      },
      {
        "category": "console",
        "timestamp": 1556893941.0,
        "message": "%c prev state color: #9E9E9E; font-weight: bold [object Object]",
        "type": "default"
      },
      {
        "category": "console",
        "timestamp": 1556893941.0,
        "message": "%c next state color: #4CAF50; font-weight: bold [object Object]",
        "type": "default"
      },
      {
        "category": "sentry",
        "timestamp": 1556893945.0,
        "message": "Error: Sentry: TEST crash",
        "type": "default",
        "level": "fatal"
      }
    ]
  },
  "sentry.interfaces.Exception": {
    "exc_omitted": null,
    "values": [
      {
        "stacktrace": {
          "frames": [
            {
              "function": "callFunctionReturnFlushedQueue",
              "platform": "javascript",
              "abs_path": "app:///[native code]",
              "in_app": false,
              "filename": "app:///[native code]"
            },
            {
              "function": "touchableHandlePress",
              "abs_path": "app:///index.bundle",
              "in_app": false,
              "platform": "javascript",
              "lineno": 64988,
              "colno": 47,
              "filename": "app:///index.bundle"
            },
            {
              "function": "crash",
              "abs_path": "app:///index.bundle",
              "in_app": false,
              "platform": "javascript",
              "lineno": 93710,
              "colno": 22,
              "filename": "app:///index.bundle"
            }
          ],
          "has_system_frames": false,
          "frames_omitted": null
        },
        "mechanism": null,
        "raw_stacktrace": null,
        "value": "Sentry: TEST crash",
        "thread_id": 99,
        "module": null,
        "type": "Error"
      }
    ]
  },
  "sentry.interfaces.User": {
    "id": "b5f212b4-9112-4253-86cc-11583ac1945a"
  },
  "type": "error",
  "version": "7"
}

Artifacts

Web UI

Cut and pasted from Release artifacts page:

Release com.mycompany.app-1.4.21

Artifacts
NAME                    SIZE
~/index.bundle          8.1 MB
~/main.bundle.map.js    14.7 MB

sourceMappingURL

$ tail -c 50 .xcodebuild/main.jsbundle
//# sourceMappingURL=main.bundle.map.js
like image 970
Ashley Coolman Avatar asked May 07 '19 10:05

Ashley Coolman


People also ask

How do I configure sentry in react?

Step 1: Set up a Sentry ProjectCreate a free Sentry account at sentry.io. After creating an account, click the Create project button. Now, select React as the platform of our project and enter a project name. Click Create Project to finish setting up a new Sentry project.

What is Sourcemap in react native?

Using our source map library you can upload source maps to unminify stack traces and get human-readable method names, files, and line numbers. To configure your project to upload source maps and native mappings automatically, follow the showing full stacktraces guide for React Native.


1 Answers

After MONTHS, we realised we had to write client code to knit in the Distribution and Release....

    const configureSentry = () => {
        Sentry.config(config.sentry.dsn).install();
        Sentry.setDist(DeviceInfo.getBuildNumber());
        Sentry.setRelease(DeviceInfo.getBundleId() + '-' + DeviceInfo.getVersion());
    };
like image 68
Ashley Coolman Avatar answered Oct 18 '22 20:10

Ashley Coolman