Troubleshooting

If you need help solving issues with your Sentry JavaScript SDK integration, you can read the edge cases documented here. If you need additional help, you can view our forums, and customers on a paid plan may also contact support.

Debugging Additional Data

You can view the JSON payload of an event to see how Sentry stores additional data in the event. The shape of the data may not exactly match the description.

Red box highlighting where to find the JSON connected to an event

For more details, see the full documentation on Event Payload.

Max JSON Payload Size

maxValueLength has a default value of 250, but you can adjust this value according to your needs if your messages are longer. Please note that not every single value is affected by this option.

CORS Attributes and Headers

To gain visibility into a JavaScript exception thrown from scripts originating from different origins, do two things:

  1. Add a crossorigin=”anonymous” script attribute
Copied
 <script src="http://another-domain.com/app.js" crossorigin="anonymous"></script>

The script attribute tells the browser to fetch the target file “anonymously.” Potentially user-identifying information like cookies or HTTP credentials won’t be transmitted by the browser to the server when requesting this file.

  1. Add a Cross-Origin HTTP header
Copied
Access-Control-Allow-Origin: *

Cross-Origin Resource Sharing (CORS) is a set of APIs (mostly HTTP headers) that dictate how files ought to be downloaded and served across origins.

By setting Access-Control-Allow-Origin: *, the server is indicating to browsers that any origin can fetch this file. Alternatively, you can restrict it to a known origin you control:

Copied
 Access-Control-Allow-Origin: https://www.example.com

Most community CDNs properly set an Access-Control-Allow-Origin header.

Copied
 $ curl --head https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.js | \
 grep -i "access-control-allow-origin"

 Access-Control-Allow-Origin: *

instrument.js Line Numbers for Console Log statements

If instrument.js displays in your console while debugging, add Sentry to your framework blackboxing settings like: /@sentry/ so Chrome ignores the SDK stackframes when debugging.

Dealing with Ad-Blockers

When you are using our CDN, ad-blocking or script-blocking extensions may prevent our SDK from being fetched and initialized properly. Because of this, any call to SDKs API will fail and may cause your application to misbehave. If this applies to your use-case, any of the following solutions will mitigate this issue.

The best way to deal with script-blocking extensions is to use the SDK package directly through the npm and bundle it with your application. This way, you can be sure that the code will be always be there as you expect it to be.

The second way is to download the SDK from our CDN and host it yourself. This way, the SDK will still be separated from the rest of your code, but you'll be certain that it won't be blocked since its origin will be the same as the origin of your website.

You can easily fetch it using curl or any other similar tool:

Copied
$ curl https://browser.sentry-cdn.com/5.20.1/bundle.min.js -o sentry.browser.5.20.1.min.js -s

The last option is to use Proxy guard, which will make sure that your code won't break, even when you call our SDK, which was blocked. Proxy is supported by all browser except Internet Explorer, though there are no extensions in this browser. Also if Proxy is not in any of your user's browser, it will be silently skipped, so you don't have to worry about it breaking anything.

Place this snippet immediately above the <script> tag containing our CDN bundle. The snippet in a readable format presents like this:

Copied
if ("Proxy" in window) {
  var handler = {
    get: function(_, key) {
      return new Proxy(function(cb) {
        if (key === "flush" || key === "close") return Promise.resolve();
        if (typeof cb === "function") return cb(window.Sentry);
        return window.Sentry;
      }, handler);
    },
  };
  window.Sentry = new Proxy({}, handler);
}

If you would like to copy and paste the snippet directly, here it is minified:

Copied
<script>
  if ("Proxy" in window) {
    var n = {
      get: function(o, e) {
        return new Proxy(function(n) {
          return "flush" === e || "close" === e
            ? Promise.resolve()
            : "function" == typeof n
            ? n(window.Sentry)
            : window.Sentry;
        }, n);
      },
    };
    window.Sentry = new Proxy({}, n);
  }
</script>

Using a Client directly

To be able to manage several Sentry instances without any conflicts between them you need to create your own Client. This also helps to prevent tracking of any parent application errors in case your application is integrated inside of it. In this example we use @sentry/browser but it's also applicable to @sentry/node.

Copied
import { BrowserClient } from "@sentry/browser";

const client = new BrowserClient({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
});

client.captureException(new Error("example"));

While the above sample should work perfectly fine, some methods like configureScope and withScope are missing on the Client because the Hub takes care of the state management. That's why it may be easier to create a new Hub and bind your Client to it. The result is the same but you will also get state management with it.

Copied
import { BrowserClient, Hub } from "@sentry/browser";

const client = new BrowserClient({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
});

const hub = new Hub(client);

hub.configureScope(function(scope) {
  scope.setTag("a", "b");
});

hub.addBreadcrumb({ message: "crumb 1" });
hub.captureMessage("test");

try {
  a = b;
} catch (e) {
  hub.captureException(e);
}

hub.withScope(function(scope) {
  hub.addBreadcrumb({ message: "crumb 2" });
  hub.captureMessage("test2");
});

Dealing with integrations

Integrations are setup on the Client, if you need to deal with multiple clients and hubs you have to make sure to also do the integration handling correctly. Here is a working example of how to use multiple clients with multiple hubs running global integrations.

Copied
import * as Sentry from "@sentry/browser";

// Very happy integration that'll prepend and append very happy stick figure to the message
class HappyIntegration {
  constructor() {
    this.name = "HappyIntegration";
  }

  setupOnce() {
    Sentry.addGlobalEventProcessor(event => {
      const self = Sentry.getCurrentHub().getIntegration(HappyIntegration);
      // Run the integration ONLY when it was installed on the current Hub
      if (self) {
        event.message = `\\o/ ${event.message} \\o/`;
      }
      return event;
    });
  }
}

HappyIntegration.id = "HappyIntegration";

const client1 = new Sentry.BrowserClient({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  integrations: [...Sentry.defaultIntegrations, new HappyIntegration()],
  beforeSend(event) {
    console.log("client 1", event);
    return null; // Returning null does not send the event
  },
});
const hub1 = new Sentry.Hub(client1);

const client2 = new Sentry.BrowserClient({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", // Can be a different DSN
  integrations: [...Sentry.defaultIntegrations, new HappyIntegration()],
  beforeSend(event) {
    console.log("client 2", event);
    return null; // Returning null does not send the event
  },
});
const hub2 = new Sentry.Hub(client2);

hub1.run(currentHub => {
  // The hub.run method makes sure that Sentry.getCurrentHub() returns this hub during the callback
  currentHub.captureMessage("a");
  currentHub.configureScope(function(scope) {
    scope.setTag("a", "b");
  });
});

hub2.run(currentHub => {
  // The hub.run method makes sure that Sentry.getCurrentHub() returns this hub during the callback
  currentHub.captureMessage("x");
  currentHub.configureScope(function(scope) {
    scope.setTag("c", "d");
  });
});
You can edit this page on GitHub.