Content derived from:Docs. Sentry. IO/platforms/j…

A series of

  • 1 minute Quick use of The latest version of Docker Sentry-CLI – create version
  • Quick use of Docker start Sentry-CLI – 30 seconds start Source Maps

Mind maps

Quick start

Sentry’s React SDK supports automatic reporting of errors and exceptions. The SDK is a wrapper around @sentry/ Browser that adds React related functionality. All methods available in @sentry/browser can be imported from @sentry/ React.

The installation

Sentry captures data by using the SDK in the application Runtime.

# use NPM
npm install --save @sentry/react @sentry/tracing
# to use yarn
yarn add @sentry/react @sentry/tracing


export const _frontmatter = {}
Copy the code

configuration

Configuration should occur early in the application lifecycle.

import React from "react";
import ReactDOM from "react-dom";
import * as Sentry from "@sentry/react";
import { Integrations } from "@sentry/tracing";
import App from "./App";

Sentry.init({
  dsn: "https://[email protected]/0".integrations: [new Integrations.BrowserTracing()],

  // We recommend adjusting this value in production or using tracesSampler for finer control
  tracesSampleRate: 1.0}); ReactDOM.render(<App />.document.getElementById("root"));

// Can also be used with React Concurrent Mode
// ReactDOM.createRoot(document.getElementById('root')).render(<App />);
Copy the code

Once done, all unhandled exceptions are automatically caught by Sentry.

Add the Error Boundary

If you are using React 16 or later, you can use the Error Boundary component to automatically send Javascript errors inside the component tree to Sentry and set up the rollback UI.

Set the React the Router

The React Router integration is designed to work with our trace package. Learn more about React Router Integration and its options in the configuration section below.

Application of story

To apply Sentry to Redux, learn more about Redux Integration and its options in the configuration section below.

validation

This code snippet contains an intentional error, so you can test everything immediately after setting it up:

return <button onClick={methodDoesNotExist}>Break the world</button>;
Copy the code

component

The Sentry React SDK exposes custom components for first-level integration with the React framework.

React Error Boundary

The React SDK exports an error bound component that uses the React Component API to automatically catch JavaScript errors and send them from within the React component tree to Sentry.

import React from "react";
import * as Sentry from "@sentry/react";

<Sentry.ErrorBoundary fallback={<p>An error has occurred</p>} ><Example />
</Sentry.ErrorBoundary>;
Copy the code

Sentry Error Boundary can also be used as a higher-order component.

import React from "react";
import * as Sentry from "@sentry/react";

Sentry.withErrorBoundary(Example, { fallback: <p>an error has occurred</p> });
Copy the code

Note: In Development mode React rethrows errors caught within error boundaries. This will cause two errors to be reported to Sentry using the above Settings, but this will not happen in your production release.

In the Example below, when the
component encounters an error, the < sentry. ErrorBoundary> component sends the data and component tree about the error to Sentry, opens the user feedback dialog, and renders the Fallback UI.

import React from "react";
import * as Sentry from "@sentry/react";

import { Example } from ".. /example";

function FallbackComponent() {
  return <div>An error has occurred</div>;
}

const myFallback = <FallbackComponent />;
// Alternatively:
// const myFallback = () => <FallbackComponent />;

class App extends React.Component {
  render() {
    return (
      <Sentry.ErrorBoundary fallback={myFallback} showDialog>
        <Example />
      </Sentry.ErrorBoundary>); }}export default App;
Copy the code

options

The ErrorBoundary component exposes various properties that can be passed in for additional configuration. There are no required options, but we strongly recommend that you set up the Fallback component.

showDialog (boolean)

  • whenError BoundaryShould be rendered when an error is caughtSentry User Feedback Widget.

dialogOptions (Object)

  • Passed to theSentry User Feedback WidgetOptions. See all possible customization options below.
    • Docs. Sentry. IO/platforms/j…

fallback (React.ReactNode or Function)

  • To be rendered when an error boundary catches an errorReactElements. It can be practicalReactElements (i.e.<Fallback />), or returnReactFunction of the element. If you provide a function,SentryIt is invoked with additional information and helper (see the example below).

onError (Function)

  • whenError BoundaryThe function called when an error is encountered. If you want to propagate errors toReduxOr you want to check for any side effects that might occur due to an error,onErrorVery useful.

onUnmount (Function)

  • inErrorBoundary componentWillUnmount()The function called on.

BeforeCapture (Function) * (available for versions 5.20.0 and later)

  • Before sending an error toSentryThe function that was called earlier allows additional labels (tag) or context (context) to the error.

The sample

Set the Fallback function (render properties)

Here is an example where the fallback property of the render property method is used to display the Fallback UI in case of an error. When reset using the resetError() API provided by the component via render properties, the Fallback UI returns to the standard component state.

import React from "react";
import * as Sentry from "@sentry/react";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: "This is my app"}; }render() {
    return (
      <Sentry.ErrorBoundary
        fallback={({ error.componentStack.resetError}) = > (
          <React.Fragment>
            <div>You have encountered an error</div>
            <div>{error.toString()}</div>
            <div>{componentStack}</div>
            <button
              onClick={()= > {
                this.setState({ message: "This is my app" });
                {/* When resetError() is called it will remove the Fallback component */}
                {/* and render the Sentry ErrorBoundary's children in their initial state */}
                resetError();
              }}
            >
              Click here to reset!
            </button>
          </React.Fragment>
        )}
      >
        <div>{this.state.message}</div>
        {/* on click, this button sets an Object as a message, not a string. */}
        {/* which will cause an error to occur in the component tree */}
        <button
          onClick={()= > this.setState({ message: { text: "Hello World" } })}
        >
          Click here to change message!
        </button>
      </Sentry.ErrorBoundary>); }}export default App;
Copy the code

Use multiple error boundaries

(Version 5.20.0 and later available)

When using more than one error boundary, we recommend using beforeCapture to set tags/context so that you can know which error boundary occurred. In the example below, we attach the tag to the error based on the error render path.

import React from 'react';
import * as Sentry from '@sentry/react';

function App({ props }) {
  return (
    <React.Fragment>
      <Sentry.ErrorBoundary
        beforeCapture={(scope)= > {
          scope.setTag("location", "first");
          scope.setTag("anotherTag", "anotherValue");
        }}
      >
        <Route to="path/to/first" component={First} />
      </Sentry.ErrorBoundary>
      <Sentry.ErrorBoundary
        beforeCapture={(scope)= > {
          scope.setTag("location", "second");
        }}
      >
        <Route to="path/to/second" component={Second} />
      </Sentry.ErrorBoundary>
    </React.Fragment>
  );
}

export default App;
Copy the code

React Profiler

@sentry/ React exports a higher-order withProfiler component that append the React related span to the current active transaction on the scope.

In the example below, the withProfiler higher-order component is used to detect App components.

import React from "react";
import * as Sentry from "@sentry/react";

class App extends React.Component {
  render() {
    return (
      <FancyComponent>
        <NestedComponent someProp={2} />
        <AnotherComponent />
      </FancyComponent>); }}export default Sentry.withProfiler(App);
Copy the code

React Profiler currently uses three different types of op-codes to generate spans: React. Mount, React. Render, and React.

react.mount

  • Represents the component being analyzedmountThe span of time required.

react.render

  • Represents the time span of the parsed component on the page. Only when a transaction occursmountunmountThis span is generated when the component is being parsed.

react.update

  • Represents the span at which the analyzed component is updated. Only if the component being analyzed has beenmountIs generated whenspan.

In React Strict Mode, some component methods will be called twice. This can lead to repeated react.mount spans in transactions. React Strict Mode only runs in development Mode, so this does not affect your production tracking.

Profiler options

The withProfiler advanced component has a variety of options for further customization. They can be passed to the withProfiler function as a second argument.

export default Sentry.withProfiler(App, { name: "CustomAppName" });
Copy the code

name (string)

  • The name of the component being analyzed. By default, the name is taken from the component’sdisplayNameProperty or componentnameProperties.

includeRender (boolean)

  • Whether it should beProfilercreatereact.renderSpan. The default istrue.

includeUpdates (boolean)

  • react.updateSpans should be driven byProfilerTo create. The default istrue. For components that will undergo multiple re-renders, such as text inputtext inputComponent), we recommend setting this property tofalseBecause of the generatedspanIt can be very noisy.

configuration

The basic options

The SDK can be configured using a variety of options. These options are largely standardized in the SDK, but there are some differences in how they better fit platform features. Options are set when the SDK is first initialized.

Options are passed as objects to the init() function:

Sentry.init({
  dsn: "https://[email protected]/0".maxBreadcrumbs: 50.debug: true});Copy the code

Common options

A list of common options across SDKS. These will work more or less the same in all SDKS, but there will be some subtle differences to better support the platform. Options that can be read from environment variables (SENTRY_DSN, SENTRY_ENVIRONMENT, SENTRY_RELEASE) are automatically read.

dsn

The DSN tells the SDK where to send the event. If this value is not provided, the SDK will try to read it from the SENTRY_DSN environment variable. If this variable also does not exist, the SDK will not send any events.

Fallback is not applied at runtime without a process environment such as a browser.

More:Docs. Sentry. IO/product/sen…

debug

Enable or disable debug mode. If debugging is enabled, the SDK will try to print useful debugging information if there is a problem sending events. The default is always false. It is generally not recommended to turn it on in production, although turning on debug mode does not raise any security issues.

release

Set the release. Some SDKS will try to configure release automatically, but it is best to set release manually to ensure that it is synchronized with your Deploy Integrations or Source Map Uploads. Release names are strings, but Sentry detects certain formats, and they may be rendered differently.

More:Docs. Sentry. IO/product/rel…

By default, the SDK will try to read this value from the environment variable SENTRY_RELEASE (in the browser SDK, it will be read from window.sentry_release, if available).

environment

Set up the environment. This string is free-form and is not set by default. A release can be associated with multiple environments to separate them in the UI (consider staging, prod, or the like).

By default, the SDK will try to read this value from the SENTRY_ENVIRONMENT environment variable (except the browser SDK).

tunnel

Set the URL that will be used to transfer captured events instead of using DSN. This can be used to resolve ad-blockers or for finer control of events sent to Sentry. This option requires the implementation of a custom server endpoint.

More:Docs. Sentry. IO/platforms/j…

sampleRate

Configure the sampling rate for error events, ranging from 0.0 to 1.0. The default value is 1.0, which means 100% error events were sent. If set to 0.1, only 10% of error events are sent. Events are chosen at random.

maxBreadcrumbs

This variable controls the total number of crumbs that should be captured. The default value is 100.

attachStacktrace

When enabled, a stack trace is automatically attached to all recorded messages. Stack traces are always attached to exceptions; However, when this option is set, the stack trace is also sent with the message. For example, this option means that the stack trace is displayed next to all log messages.

This option defaults to off.

The grouping in Sentry is different for events with and without stack traces. So when you enable or disable this Flag for certain events, you get new groups.

denyUrls

List of strings or regular expression patterns that match the wrong URL that should not be sent to Sentry. By default, all errors are sent. This is a “contains” that matches the entire file URL. So, if you add foo.com, it will also match at https://bar.com/myfile/foo.com. By default, all errors are sent.

allowUrls

A list of strings or a legacy alias for a regular expression pattern that matches the wrong URL, which should be sent specifically to Sentry. By default, all errors are sent. This is a “contains” that matches the entire file URL. So, if you add foo.com to the it, it will also match at https://bar.com/myfile/foo.com. By default, all errors will be sent.

autoSessionTracking

When set to true, the SDK will send session events to Sentry. This is supported in all browser SDKS, and each page load and page navigation issues a session to Sentry. In the mobile SDK, the session ends when the application is in the background for more than 30 seconds.

initialScope

Data to be set to the initial scope. The initial scope can be defined as an object or a callback function, as shown below.

Object:

Sentry.init({
  dsn: "https://[email protected]/0".debug: true.initialScope: {
    tags: {"my-tag": "my value"},
    user: {id: 42.email: "[email protected]"}}});Copy the code

Callback function:

Sentry.init({
  dsn: "https://[email protected]/0".debug: true.initialScope: scope= > {
    scope.setTags({ a: 'b' });
    returnscope; }});Copy the code
maxValueLength

The maximum number of characters a single value can have before it is truncated (the default is 250).

normalizeDepth

The Sentry SDK normalizes any context data to a given depth. Any key that contains data deeper than this structure will be pruned and marked with its type ([Object] or [Array]) and will not traverse the tree further. By default, the walk performs 3 levels of depth.

Integrated configuration

For many platforms, SDK integration can be configured with them. On some platforms, this is part of the init() call, while on others, a different pattern applies.

integrations

In some SDKS, this parameter is used to configure integration during library initialization.

More:

defaultIntegrations

This can be used to disable integrations added by default. When set to false, default integrations are not added.

Hooks

These options can be used to hook the SDK in various ways to customize event reporting.

beforeSend

This function, called with sdK-specific event objects, can return the modified event object or nothing to skip reporting the event. For example, this can be used to manually strip the PII before sending.

beforeBreadcrumb

This function is called with an SDK-specific breadcrumb object before the breadcrumb is added to the scope. When nothing is returned from this function, the breadcrumb is removed. To pass the breadcrumb, return the first parameter, which contains the breadcrumb object. The callback usually gets a second parameter (called “hint”) that contains the original object that created the breadcrumb to further customize the appearance of the breadcrumb.

Transport options

Transports is used to send events to Sentry. Transport can be customized to some extent to better support highly specific deployments.

transport

Switch out the transport used to send events. How it works depends on the SDK. For example, it can be used to capture events for unit testing, or to send events through more complex Settings that require proxy authentication.

Trace options

tracesSampleRate

A number between 0 and 1 that controls the percentage probability that a given transaction will be sent to Sentry. (0 means 0% and 1 means 100%) the same applies to all transactions created in the application. This or tracesSampler must be defined to enable tracing.

tracesSampler

A function is responsible for determining the percentage probability that a given transaction will be sent to Sentry. It will automatically be passed information about the transaction and the context in which it was created, and must return a number between 0(with a 0% chance of being sent) and 1(with a 100% chance of being sent). It can also be used to filter transactions, returning 0 for unwanted transactions. This or tracesSampleRate must be defined to enable tracking.

integration

The default integration

All of Sentry’s SDKS provide integrated, extensible SDK functionality.

System integration is enabled by default to integrate into the standard library or the interpreter itself. They are documented so you can either understand what they do or disable them if they cause problems.

Enabled by default
InboundFilters

Import name: Sentry.Integrations.InboundFilters

With this integration, you can ignore specific errors based on the type, message, or URL in a given exception.

By default, it ignores errors starting with Script Error or Javascript error: Script error.

To configure this integration, use the ignoreErrors, denyUrls, and allowUrls SDK options directly. Keep in mind that denyURL and allowURL are only valid for caught exceptions, not raw message events.

FunctionToString

Import name: Sentry.Integrations.FunctionToString

This integration allows the SDK to provide the original function and method names, even if our error or breadcrumbs handlers wrap them.

TryCatch

Import name: Sentry.Integrations.TryCatch

This integration encapsulates the native Time and Events APIs (setTimeout, setInterval, requestAnimationFrame, AddEventListener/removeEventListener) in a try/catch block async exception handling.

Breadcrumbs

Import name: Sentry.Integrations.Breadcrumbs

This integration encapsulates the native API to capture breadcrumbs. By default, the Sentry SDK wraps all apis.

Available options:

{
  // Records calls to 'console.log', 'console.debug', etc
  console: boolean;

  // Logs all clicks and keystrokes
  // - When an object with 'serializeAttribute' key is supplied,
  Breadcrumb integration looks for the given attribute in the DOM element while generating breadcrumb paths.
  // Matched elements are followed by their custom attributes, not their 'ID' or 'class' names.
  dom: boolean | { serializeAttribute: string | string[] };

  // Record the 'HTTP' requests completed using the 'Fetch API'
  fetch: boolean;

  // Record the call to history.pushState
  history: boolean;

  // Record whenever we send events to the server
  sentry: boolean;

  // Log HTTP requests completed using the XHR API
  xhr: boolean;
}
Copy the code
GlobalHandlers

Import name: Sentry.Integrations.GlobalHandlers

This integration attaches global handlers to catch uncaught exceptions and unhandled rejections.

Available options:

{
  onerror: boolean;
  onunhandledrejection: boolean;
}
Copy the code
LinkedErrors

Import name: Sentry.Integrations.LinkedErrors

This integration allows you to configure Linked errors. They are recursively read to the specified limit and lookups are performed by a specific key. By default, the Sentry SDK sets the limit to 5 and uses the key cause.

Available options:

{
  key: string;
  limit: number;
}
Copy the code

Here’s an example of code for how to do this:

document
  .querySelector("#get-reviews-btn")
  .addEventListener("click".async event => {
    const movie = event.target.dataset.title;
    try {
      const reviews = await fetchMovieReviews(movie);
      renderMovieReviews(reviews);
    } catch (e) {
      const fetchError = new Error(`Failed to fetch reviews for: ${movie}`); fetchError.cause = e; Sentry.captureException(fetchError); renderMovieReviewsError(fetchError); }});Copy the code
UserAgent

Import name: Sentry.Integrations.UserAgent

This integration attaches User-Agent information to events, which allows us to properly categorize and tag them with specific operating system (OS), browser, and version information.

Dedupe

Import name: Sentry.Integrations.Dedupe

This integration eliminates duplicate data for some events. This is helpful if you receive a lot of repeated errors. Please note that Sentry only compares stack traces with fingerprints. This integration is enabled for browsers by default.

import * as Sentry from "@sentry/browser";
import { Dedupe as DedupeIntegration } from "@sentry/integrations";

Sentry.init({
  dsn: "https://[email protected]/0".integrations: [new DedupeIntegration()],
});
Copy the code

CDN

<script
  src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js"
  integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"
  crossorigin="anonymous"
></script>

<script
  src="https://browser.sentry-cdn.com/6.12.0/dedupe.min.js"
  integrity="sha384-3IMGY+DN27Yns7KDiKL3sOWXBYlILQ/bxLogt02NG7DL7qEJHIMbpnXfqNlO0J8G"
  crossorigin="anonymous"
></script>

Sentry.init({
  dsn: "https://[email protected]/0",
  integrations: [new Dedupe()],
});
Copy the code
Modifying system Integration

To disable system integration, set defaultIntegrations: false when init() is called.

To override their Settings, provide a new instance with your configuration to integration options. For example, to close the browser to capture console call: integrations: [new Sentry. Integrations. Breadcrumbs (} {the console: false)].

Delete the integration

This example removes the default enabled integration for adding breadcrumbs to events:

Sentry.init({
  // ...

  integrations: function(integrations) {
    // integrations will be all default integrations
    return integrations.filter(function(integration) {
      returnintegration.name ! = ="Breadcrumbs"; }); }});Copy the code

Pluggable integration

These pluggable integrations are snippets of code that add functionality to a particular application and/or framework. We document them so you can see what they do, and you can enable them.

How to enable

Install the @Sentry/Integrations package and provide a new instance with your configuration options to Integrations. Once the SDK is loaded, plug-ins are included.

Example:

import * as Sentry from "@sentry/browser";
import { ReportingObserver as ReportingObserverIntegration } from "@sentry/integrations";

Sentry.init({
  dsn: "https://[email protected]/0".integrations: [new ReportingObserverIntegration()],
});
Copy the code

CDN

<script
  src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js"
  integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"
  crossorigin="anonymous"
></script>

<script
  src="https://browser.sentry-cdn.com/6.12.0/reportingobserver.min.js"
  integrity="sha384-20D83MPBNSRANJFguhj0o9Qo7p9MCemwdMMQXotwA8742WuIwga85k+T7qEgIMWK"
  crossorigin="anonymous"
></script>

Sentry.init({
  dsn: "https://[email protected]/0",
  integrations: [new ReportingObserver()],
});
Copy the code
ExtraErrorData

Import name: Sentry.Integrations.ExtraErrorData

This integration extracts all non-native attributes from the error object and attaches them to the event as extra data.

Available options:

import * as Sentry from "@sentry/browser";
import { ExtraErrorData as ExtraErrorDataIntegration } from "@sentry/integrations";

Sentry.init({
  dsn: "https://[email protected]/0".integrations: [new ExtraErrorDataIntegration(
    {
      // limit of how deep the object serializer should go. Anything deeper than limit will
      // be replaced with standard Node.js REPL notation of [Object], [Array], [Function] or
      // a primitive value. Defaults to 3.
      depth: number; })]});Copy the code

CDN

<script
  src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js"
  integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"
  crossorigin="anonymous"
></script>

<script
  src="https://browser.sentry-cdn.com/6.12.0/extraerrordata.min.js"
  integrity="sha384-DMO/ZWwA4ztkOtskx1Uad3cH6lbfSA/PGdW2IZ7A/c2qd/BU6zh5xiJ5D4nxJbye"
  crossorigin="anonymous"
></script>

Sentry.init({
  dsn: "https://[email protected]/0",
  integrations: [new ExtraErrorData(
    {
      // limit of how deep the object serializer should go. Anything deeper than limit will
      // be replaced with standard Node.js REPL notation of [Object], [Array], [Function] or
      // a primitive value. Defaults to 3.
      depth: number;
    }
  )],
});
Copy the code
CaptureConsole

Import name: Sentry.Integrations.CaptureConsole

This integration captures all Console API calls and redirects them to Sentry using captureMessage calls. It then refires to preserve the default native behavior.

import * as Sentry from "@sentry/browser";
import { CaptureConsole as CaptureConsoleIntegration } from "@sentry/integrations";

Sentry.init({
  dsn: "https://[email protected]/0".integrations: [new CaptureConsoleIntegration(
    {
      // array of methods that should be captured
      // defaults to ['log', 'info', 'warn', 'error', 'debug', 'assert']
      levels: string[]; })]});Copy the code

CDN

<script
  src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js"
  integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"
  crossorigin="anonymous"
></script>

<script
  src="https://browser.sentry-cdn.com/6.12.0/captureconsole.min.js"
  integrity="sha384-FJ5n80A08NroQF9DJzikUUhiCaQT2rTIYeJyHytczDDbIiejfcCzBR5lQK4AnmVt"
  crossorigin="anonymous"
></script>

Sentry.init({
  dsn: "https://[email protected]/0",
  integrations: [new CaptureConsole(
    {
      // array of methods that should be captured
      // defaults to ['log', 'info', 'warn', 'error', 'debug', 'assert']
      levels: string[];
    }
  )],
});
Copy the code
Debug

Import name: Sentry.Integrations.Debug

With this integration, you can examine the contents of the processed event, which is passed to beforeSend and effectively sent to the Sentry SDK. Whenever registered, it will always run as the final integration.

Available options:

import * as Sentry from "@sentry/browser";
import { Debug as DebugIntegration } from "@sentry/integrations";

Sentry.init({
  dsn: "https://[email protected]/0".integrations: [new DebugIntegration(
    {
      // trigger DevTools debugger instead of using console.log
      debugger: boolean;

      // stringify event before passing it to console.logstringify: boolean; })]});Copy the code

CDN

<script
  src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js"
  integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"
  crossorigin="anonymous"
></script>

<script
  src="https://browser.sentry-cdn.com/6.12.0/debug.min.js"
  integrity="sha384-OIzIETBTnmaXcnCVlI4DzHq1+YxDdBS6uyZPp8yS60YZNUqzIQvrudJplBqEZ09K"
  crossorigin="anonymous"
></script>

Sentry.init({
  dsn: "https://[email protected]/0",
  integrations: [new Debug(
    {
      // trigger DevTools debugger instead of using console.log
      debugger: boolean;

      // stringify event before passing it to console.log
      stringify: boolean;
    }
  )],
});
Copy the code
Offline

Import name: Sentry.Integrations.Offline

This integration uses the Web browser’s online and offline events to detect when no network connection is available. If offline, it saves the event to the Web browser’s client store (typically IndexedDB) and then automatically uploads the event when the network connection is restored.

Online and offline events

  • Developer.mozilla.org/en-US/docs/…

This plug-in does not attempt to provide local storage or retry for other scenarios. For example, if the browser has a local connection but no Internet connection, it may report that it is online, and in that case, Sentry’s Offline plug-in does not attempt to save or retry any sending failures.

import * as Sentry from "@sentry/browser";
import { Offline as OfflineIntegration } from "@sentry/integrations";

Sentry.init({
  dsn: "https://[email protected]/0".integrations: [new OfflineIntegration(
    {
      // limit how many events will be localled saved. Defaults to 30.
      maxStoredEvents: number; })]});Copy the code

CDN

<script
  src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js"
  integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"
  crossorigin="anonymous"
></script>

<script
  src="https://browser.sentry-cdn.com/6.12.0/offline.min.js"
  integrity="sha384-rRq5WRQ3OncIj4lduaVZMtyfVwZnqeWXM0nXyXckOrhFLS2mlKEYX+VAlbLlIZL4"
  crossorigin="anonymous"
></script>

Sentry.init({
  dsn: "https://[email protected]/0",
  integrations: [new Offline(
    {
      // limit how many events will be localled saved. Defaults to 30.
      maxStoredEvents: number;
    }
  )],
});
Copy the code
RewriteFrames

Import name: Sentry.Integrations.RewriteFrames

This integration allows you to apply transformations to each frame of the stack trace. In a Streamlined scenario, it can be used to change the name of the file frame from which it comes, or it can be provided with arbitrary transformations using iterative functions.

On Windows machines, you must use the Unix path and skip the volume number in the root option to enable it. For example C:\\Program Files\\Apache\ WWW will not work, but /Program Files/Apache/ WWW will work.

Available options:

import * as Sentry from "@sentry/browser";
import { RewriteFrames as RewriteFramesIntegration } from "@sentry/integrations";

Sentry.init({
  dsn: "https://[email protected]/0".integrations: [new RewriteFramesIntegration(
    {
      // root path that will be stripped from the current frame's filename by the default iteratee if the filename is an absolute path
      root: string;

      // a custom prefix that will be used by the default iteratee (default: `app://`)
      prefix: string;

      // function that takes the frame, applies a transformation, and returns it
      iteratee: (frame) = >frame; })]});Copy the code

CDN

<script
  src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js"
  integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"
  crossorigin="anonymous"
></script>

<script
  src="https://browser.sentry-cdn.com/6.12.0/rewriteframes.min.js"
  integrity="sha384-WOm9k3kzVt1COFAB/zCXOFx4lDMtJh/2vmEizIwgog7OW0P/dPwl3s8f6MdwrD7q"
  crossorigin="anonymous"
></script>

Sentry.init({
  dsn: "https://[email protected]/0",
  integrations: [new RewriteFrames(
    {
      // root path that will be stripped from the current frame's filename by the default iteratee if the filename is an absolute path
      root: string;

      // a custom prefix that will be used by the default iteratee (default: `app://`)
      prefix: string;

      // function that takes the frame, applies a transformation, and returns it
      iteratee: (frame) => frame;
    }
  )],
});
Copy the code

Example:

For example, if the full path to the file is/WWW/SRC /app/file.js:

usage Path in the stack trace describe
RewriteFrames() app:///file.js The default behavior is to replace absolute paths other than file names and use default prefixes (app:///) as a prefix.
RewriteFrames({prefix: ‘foo/’}) foo/file.js Use prefixesfoo/Replace the default prefixapp:///.
RewriteFrames({root: ‘/www’}) app:///src/app/file.js rootIs defined as/www, so prune that part only from the beginning of the path.
ReportingObserver

Import name: Sentry.Integrations.ReportingObserver

This integration hooks into the ReportingObserver API and sends captured events to Sentry. It can be configured to handle only specific issue types.

Available options:

import * as Sentry from "@sentry/browser";
import { ReportingObserver as ReportingObserverIntegration } from "@sentry/integrations";

Sentry.init({
  dsn: "https://[email protected]/0".integrations: [new ReportingObserverIntegration(
    {
      types: <'crash'|'deprecation'|'intervention'> []; })]});Copy the code

CDN

<script
  src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js"
  integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"
  crossorigin="anonymous"
></script>

<script
  src="https://browser.sentry-cdn.com/6.12.0/reportingobserver.min.js"
  integrity="sha384-20D83MPBNSRANJFguhj0o9Qo7p9MCemwdMMQXotwA8742WuIwga85k+T7qEgIMWK"
  crossorigin="anonymous"
></script>

Sentry.init({
  dsn: "https://[email protected]/0",
  integrations: [new ReportingObserver(
    {
      types: <'crash'|'deprecation'|'intervention'>[];
    }
  )],
});
Copy the code

The React the Router integration

(applicable to5.21.0And above)

React Router support has been included in the @sentry/ React package since version 5.21.0.

Note:

The React Router integration is designed to be used with our trace SDK @Sentry/Tracing. For more details on how to set up and install the SDK, see React Performance Getting Started.

Docs. Sentry. IO/platforms/j…

We support integration with React Router 3, 4, and 5.

React Router v4/v5

To use Router Integration, import and set up custom route detection using custom History. Be sure to use the Router component with createBrowserHistory (or its equivalent).

import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';

import * as Sentry from '@sentry/react';
import { Integrations } from '@sentry/tracing';

const history = createBrowserHistory();

Sentry.init({
  integrations: [
    new Integrations.BrowserTracing({
      // Can also use reactRouterV3Instrumentation or reactRouterV4Instrumentation
      routingInstrumentation: Sentry.reactRouterV5Instrumentation(history),
    }),
  ],

  // We recommend adjusting this value in production, or using tracesSampler
  // for finer control
  tracesSampleRate: 1.0});// ...

// In your App render:
render() {
  return (
    // Use custom history with a Router component
    <Router history={history}>
      <Components />
    </Router>
  );
}
Copy the code

Now you should use the React Router detection to integrate generated Pageload/Navigation transactions from BrowserTracing.

Parameterize the transaction name

For parameterized trading name (for example/teams / : teamid/user / : userid rather than/teams / 123 / user / 345), you must be granted the SDK access to the matching path routing rendering. This is because the SDK does not have a static route configuration that can be used in React Router V4 / V5. There are two ways to achieve this:

  1. Pass routing configuration objects

You can pass a set of routing configuration objects according to react-router-config. To detect function calls. You also need to provide the matchPath function exported from the react-router-dom or react-router package.

  • Github.com/remix-run/r…
import { Route, Router, Switch, matchPath } from 'react-router-dom';
import { createBrowserHistory } from 'history';

import * as Sentry from '@sentry/react';
import { Integrations } from '@sentry/tracing';

const history = createBrowserHistory();

// Array of Route Config Objects
// Make sure the order of the routes is correct. The longest url under the same parent should be placed first and in decreasing order.
const routes = [{ path: '/users/:userid' }, { path: '/users' }, { path: '/' }];

Sentry.init({
  integrations: [
    new Integrations.BrowserTracing({
      routingInstrumentation: Sentry.reactRouterV5Instrumentation(history, routes, matchPath),
    }),
  ],

  // We recommend adjusting this value in production, or using tracesSampler
  // for finer control
  tracesSampleRate: 1.0});// In your App render:
render() {
  return (
    <Router history={history}>
      <Switch>
         <Route path="/users/:userid" component={()= > <div>UserId</div>} / ><Route path="/users" component={()= > <div>Users</div>} / ><Route path="/" component={()= > <div>Home</div>} / ></Switch>
    </Router>
  );
}
Copy the code
  1. Use the Sentry Route component

Create a SentryRoute component using the withSentryRouting high-level component that updates the matching path at render time.

import {Route, Router, Switch } from 'react-router-dom';
import { createBrowserHistory } from 'history';

import * as Sentry from '@sentry/react';
import { Integrations } from '@sentry/tracing';

// Create Custom Sentry Route component
const SentryRoute = Sentry.withSentryRouting(Route);

const history = createBrowserHistory();

Sentry.init({
  integrations: [
    new Integrations.BrowserTracing({
      routingInstrumentation: Sentry.reactRouterV5Instrumentation(history),
    }),
  ],

  // We recommend adjusting this value in production, or using tracesSampler
  // for finer control
  tracesSampleRate: 1.0});render() {
  return (
    <Router history={history}>
      <Switch>
        <SentryRoute path="/users/:userid" component={()= > <div>UserId</div>} / ><SentryRoute path="/users" component={()= > <div>Users</div>} / ><SentryRoute path="/" component={()= > <div>Home</div>} / ></Switch>
    </Router>
  );
}
Copy the code
React Router v3

To use Router Integration, import and set up the custom routing tool and pass it the history, your routes, and match functions. React Router V3 support for React Router >= 3.2.0 and < 4.0.0 remains unchanged.

Redux integration

(Version 5.20.0 and later available)

Since version 5.20.0, Redux support is included in the @sentry/ React package. To apply Sentry in the story, please use initialization Redux store in the same position with Sentry. CreateReduxEnhancer.

import { createStore, compose } from "redux";
import * as Sentry from "@sentry/react";

// ...

const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  // Optionally pass options listed below
});

const store = createStore(rootReducer, sentryReduxEnhancer);

// ...
Copy the code

If you have other enhancers or middleware, such as Thunk:

const store = createStore(
  rootReducer,
  compose(applyMiddleware(thunk), sentryReduxEnhancer)
);
Copy the code

Note:

Sentry uses redux enhancer. Through enhancer, as shown above.

Do not pass it to applyMiddleware and do not call it when you pass it to the createStore method.

The depth of the Normalization

By default, the Sentry SDK normalizes any context to a depth of 3, which you may want to increase in the case of sending Redux status. You can do this by passing normalizeDepth to the sentry.init call:

Sentry.init({
  dsn: "https://[email protected]/0".normalizeDepth: 10.// Or however deep you want your state context to be.
});
Copy the code
Redux Enhancer options

The option object as the first parameter passed to the Sentry. CreateReduxEnhancer to configure it.

Note:

We recommend not sending sensitive information to Sentry, but if you do, we do our best to filter out things like user passwords.

actionTransformer (Function)

Use to remove sensitive information from action. The first argument passed to the function is the Redux action. Returns NULL to not send operations to Sentry. By default, we send all actions.

const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  actionTransformer: action= > {
    if (action.type === "GOVERNMENT_SECRETS") {
      // Return null to not log the action to Sentry
      return null;
    }
    if (action.type === "SET_PASSWORD") {
      // Return a transformed action to remove sensitive information
      return {
        ...action,
        password: null}; }returnaction; }});Copy the code

stateTransformer (Function)

Used to remove sensitive information from state. The first argument passed to the function is Redux state. Returns NULL to not append state to the event sent to Sentry. Note that if you choose not to send state to Sentry, your error may not have appended the latest version of state. By default, we attach all state changes.

const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  stateTransformer: state= > {
    if (state.topSecret.doNotSend) {
      // Return null to not send this version of the state.
      return null;
    }

    // Transform the state to remove sensitive information
    consttransformedState = { ... state,topSecret: {
        ...state.topSecret,
        // Replace sensitive information with something else
        nuclearLaunchCodes: "I love pizza".// or just remove it entirely
        hiddenTreasureLocation: null,},// You should also remove large data that is irrelevant to debugging to not clutter your Sentry issues
      giganticState: null};returntransformedState; }});Copy the code

configureScopeWithState (Function)

Called at each state update, Sentry Scope is configured with Redux state. The first argument is scope, the same scope instance you get when you call sentry.configurescope, and the second argument is the latest Redux state.

const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  configureScopeWithState: (scope, state) = > {
    // Set tag if the user is using imperial units.
    if (state.settings.useImperialUnits) {
      scope.setTag("user.usesImperialUnits".true); }}});Copy the code

Custom integration

Add custom integrations to JavaScript using the following format:

// All integration that come with an SDK can be found on Sentry.Integrations object
// Custom integration must conform Integration interface: https://github.com/getsentry/sentry-javascript/blob/master/packages/types/src/integration.ts

Sentry.init({
  // ...

  integrations: [new MyAwesomeIntegration()],
});
Copy the code

Rrweb: Session replay

Sentry provides proof-of-concept integration with RRWeb – a toolkit for recording and replaying user sessions. This is useful in diagnosing complex user behavior in rich, single-page applications.

More information:

  • www.rrweb.io/
  • Docs. Sentry. IO/platforms/j…
  • Docs. Sentry. IO/platforms/j…

configuration

To get started, you need to add @sentry/ rrWeb and the rrWeb package:

npm install --save @sentry/rrweb rrweb
Copy the code

Next, register the integration with the Sentry SDK. This will vary depending on the framework you use:

// If you're using one of our integration packages, like `@sentry/react` or
// `@sentry/angular`, substitute its name for `@sentry/browser` here
import * as Sentry from "@sentry/browser";
import SentryRRWeb from "@sentry/rrweb";

Sentry.init({
  dsn: "https://[email protected]/0".integrations: [
    new SentryRRWeb({
      / /... options}),].// ...
});
Copy the code

After capturing a Replay of the event, you will find it in the Issue Details section of the event under the Replay section.

  • More:Github.com/getsentry/s…
The sampling

To meet the needs of your organization, you may prefer to sample playback. The easiest way to do this is to make a sampling decision when initializing the Sentry SDK. For example, here’s how Sentry itself uses sampling to capture this information for employees only:

const hasReplays = getCurrentUser().isStaff;

let integrations = [];
if (hasReplays) {
  console.log("[sentry] Instrumenting session with rrweb");
  integrations.push(new SentryRRWeb());
}

Sentry.init({
  dsn: "https://[email protected]/0",
  integrations,
});

Sentry.setTag("rrweb.active", hasReplays ? "yes" : "no");
Copy the code

You’ll notice that we also set the rrWeb. active tag, which helps us identify events with replays attached that we would otherwise not be able to find. Once configured, you can simply use rrWeb. active:yes in your search query.

Release & Health

Release is the version of the code deployed into the environment. When you provide Sentry with information about your version, you can:

  • Identify issues and regressions introduced in the new release
  • Predict which commit caused the problem and who might be responsible
  • Resolve the problem by including the problem number in the commit message
  • Receive email notifications when deploying code

In addition, release is used to apply Source maps to compressed JavaScript to view the original, unconverted source code.

Binding version

The client SDK is configured with a release ID (often referred to as “version version”).

Release names cannot:

  • Contains newlines, tabs, forward slashes (/) or backslash (\)
  • Is (all) full stop (.), double full stop (.) or space ( )
  • More than200A character

This value can be arbitrary, but we recommend any of the following naming strategies:

  • Semantic versioning: package@versionpackage@version+build(e.g.,[email protected]+ 1234).
    • packageproject/appUnique identifier ofiOSOn theCFBundleIdentifier.AndroidOn thepackageName)
    • versionIs similar to thesemverThe structure of the<major>.<minor? >.<patch? >.<revision? >-<prerelease? >(iOSOn theCFBundleShortVersionString.AndroidOn theversionName)
    • buildIs to identifyappNumber of iterations (iOSOn theCFBundleVersion.AndroidOn theversionCode)
  • Commit SHA:If you useDVCS, we recommend usingIdentifies a hash(e.g.,commit SHA.da39a3ee5e6b4b0d3255bfef95601890afd80709). You can makeSentry CLIusesentry-clireleases proposal-versionThis hash value is automatically determined for supported version control systems.

Releases for each organization are global; Add project-specific prefixes to make them easier to distinguish.

Sentry.init({
  release: "[email protected]"});Copy the code

A common way to do this using JavaScript in a Node/ NPM environment is to use process.env.npm_package_version, as shown below:

  • More:Docs.npmjs.com/misc/script…
Sentry.init({
  release: "my-project-name@" + process.env.npm_package_version,
});
Copy the code

How you make versions available to your code is up to you. For example, you can use environment variables that you set during the build process.

This marks each event with a release value. We recommend that you tell Sentry a new release before deploying, as this unlocks more of the features we discussed in our documentation on Releases. However, if you don’t, Sentry will automatically create a Release entity in the system the first time it sees an event with that release ID.

  • release:Docs. Sentry. IO/product/rel…

After configuring your SDK, you can install Repository Integration or manually provide your own commit metadata for Sentry. Read our documentation on setting Up Releases for more information about integrating integrations, associated submitted associating commits, and notifying Sentry when Deploying Releases.

  • Set the releases:Docs. Sentry. IO/product/rel…

Release health

Monitor release health by looking at user adoption, application usage, crash percentage, and session data. The Release health provides insight into the impact of crashes and errors related to the user experience and reveals trends for each new issue through release details, charts, and filters.

  • health of releases : Docs. Sentry. IO/product/rel…
  • Crashes:Docs. Sentry. IO/product/rel…
  • The session data:Docs. Sentry. IO/product/rel…

The SDK automatically manages the start and end of the session when the SDK initializes.

We create a session for each page load. For single-page applications, we will create a new session for each navigation change (the History API).

We mark the session as:

  • ifunhandled errorunhandled promise rejectionBubble to the global handler and crash.
  • ifSDKAn error occurs when you catch an event that contains an exception, which includes manually caught errors.

To receive data about user adoption, such as the percentage of users crashing and the number of users adopting a particular version, set the user on initialScope when initializing the SDK.

By default, the JavaScript SDK is sending sessions. To disable the send session, set the autoSessionTracking flag to false:

Sentry.init({
  autoSessionTracking: false // default: true
});
Copy the code

The environment

Sentry automatically creates the environment when it receives an event with the environment tag. The environment is case sensitive. The environment name cannot contain newlines, Spaces, or slashes, and cannot be the string “None” or more than 64 characters. You cannot delete environments, but you can hide them.

  • hidden-environments: Docs. Sentry. IO/product/sen…
Sentry.init({
  environment: "production"});Copy the code

Environments can help you better filter issues, releases, and user feedback in sentry. IO’s problem details page, and you can learn more about this in our documentation covering using environments.

  • Environments:Docs. Sentry. IO/product/sen…

filter

Adding Sentry to your application gives you a lot of valuable information about errors and performance that you would otherwise not have access to. A lot of information is good – as long as it’s the right information and in a reasonable amount.

The Sentry SDK has several configuration options to help you filter events.

We also provide Inbound Filters to filter events in sentry. IO. However, we recommend filtering at the client level because it eliminates the overhead of sending events that you don’t actually want. Learn more about the fields available in events.

  • Inbound Filters: Docs. Sentry. IO/product/dat…
  • Fields available in an event:Develop. Sentry. Dev/SDK/event – p…

Filtering error events

Configure your SDK to filter error events by using the beforeSend callback method and configuring, enabling, or disabling the integration.

Using beforeSend

All Sentry SDKS support the beforeSend callback method. BeforeSend is called immediately before events are sent to the server, so it is the last place you can edit its data. It receives the event object as a parameter, so you can use this parameter to modify the event’s data or delete it completely (by returning NULL) based on the custom logic and data available on the event.

Sentry.init({
  // ...

  beforeSend(event, hint) {
    const error = hint.originalException;
    if (
      error &&
      error.message &&
      error.message.match(/database unavailable/i)
    ) {
      event.fingerprint = ["database-unavailable"];
    }
    returnevent; }});Copy the code

Also note that breadcrumbs can be filtered, as discussed in our breadcrumbs document.

  • breadcrumbs: Docs. Sentry. IO/product/err…

Event Hints

The before-send callback passes the Event and the second parameter hint, which contains one or more hints.

Typically, HINT saves the original exception so that you can extract additional data or influence groupings. In this example, if some type of exception is caught, the fingerprint is forced to a common value:

Sentry.init({
  // ...

  beforeSend(event, hint) {
    const error = hint.originalException;
    if (
      error &&
      error.message &&
      error.message.match(/database unavailable/i)
    ) {
      event.fingerprint = ["database-unavailable"];
    }
    returnevent; }});Copy the code

For information on which Hints are available, see:

  • hints in JavaScript: Docs. Sentry. IO/platforms/j…

When an SDK creates an event or breadcrumb for transmission, the transmission is usually created from some source object. For example, error events are typically created from logging or exception instances. For better customization, the SDK sends these objects to some callback (beforeSend, beforeBreadcrumb, or the event handler system in the SDK).

Use the Hints

Hints is available in two places:

  1. beforeSend / beforeBreadcrumb
  2. eventProcessors

Event and Breadcrumb Hints are objects that contain a variety of information for combining events or breadcrumbs. Often Hints saves raw exceptions so that additional data can be extracted or groups affected.

For events, such as Event_ID, originalException, syntheticException (internally used to generate a cleaner stack trace), and any other arbitrary data you attach.

For breadcrumbs, the use of Hints depends on the implementation. For XHR requests, the hint contains the XHR object itself; For user interactions, hints contain DOM elements, event names, and so on.

In this example, if some type of exception is caught, the fingerprint is forced to a common value:

Sentry.init({
  // ...

  beforeSend(event, hint) {
    const error = hint.originalException;
    if (
      error &&
      error.message &&
      error.message.match(/database unavailable/i)
    ) {
      event.fingerprint = ["database-unavailable"];
    }
    returnevent; }});Copy the code

Hints for Events

originalException

The original exception that causes the Sentry SDK to create the event. This is useful for changing the way the Sentry SDK groups events or extracting additional information.

syntheticException

When a string or non-error object is raised, Sentry creates a synthetic exception so that you can get a basic stack trace. This exception is stored here for further data extraction.

Hints for Breadcrumbs

event

For breadcrumbs created from browser events, the Sentry SDK typically provides the event as a hint to the breadcrumbs. For example, this can be used to extract data from the target DOM element into breadcrumbs.

level / input

For intercepting breadcrumbs created from the console log (console.log). This saves the raw input data for the original Console log level and log function.

response / input

For breadcrumbs created from the HTTP request. It holds the response object (from the FETCH API) and the input parameters of the FETCH function.

request / response / event

For breadcrumbs created from the HTTP request. This includes request and response objects (from the Node HTTP API) and Node Events (response or error).

xhr

Breadcrumbs created for HTTP requests completed through the legacy XMLHttpRequest API. This preserves the original XHR object.

Finishing Sentry

You can build a list of allowed fields that may throw acceptable exceptions. For example, if your script is loaded from cdn.example.com and your site is example.com, you can set allowUrls to:

Sentry.init({
  allowUrls: [
    /https? :\/\/((cdn|www)\.) ? example\.com/]});Copy the code

If you want to block specific urls forever, you can also use denyUrls.

Note Prior to version 5.17.0, allowUrls and denyUrls were called whitelistUrls and blacklistUrls respectively. These options are still supported for backward compatibility reasons, but they will be removed in version 6.0. For more information, see

Inclusive Language Policy:develop.sentry.dev/inclusion/

In addition, our community has compiled a list of common ignore rules for everyday things like Facebook, Chrome Extensions, etc. This is useful, and I suggest you review these to see if they apply to you. This is not the default for our SDK; This is just one highlight of an extensive example.

  • Here is the original gist:Gist.github.com/impressiver…
Sentry.init({
  ignoreErrors: [
    // Random plugins/extensions
    "top.GLOBALS".// See: http://blog.errorception.com/2012/03/tale-of-unfindable-js-error.html
    "originalCreateNotification"."canvas.contentDocument"."MyApp_RemoveAllHighlights"."http://tt.epicplay.com"."Can't find variable: ZiteReader"."jigsaw is not defined"."ComboSearch is not defined"."http://loading.retry.widdit.com/"."atomicFindClose".// Facebook borked
    "fb_xd_fragment".// ISP "optimizing" proxy - `Cache-Control: no-transform` seems to
    // reduce this. (thanks @acdha)
    // See http://stackoverflow.com/questions/4113268
    "bmi_SafeAddOnload"."EBCallBackMessageReceived".// See http://toolbar.conduit.com/Developer/HtmlAndGadget/Methods/JSInjection.aspx
    "conduitPage",].denyUrls: [
    // Facebook flakiness
    /graph\.facebook\.com/i.// Facebook blocked
    /connect\.facebook\.net\/en_US\/all\.js/i.// Woopra flakiness
    /eatdifferent\.com\.woopra-ns\.com/i./static\.woopra\.com\/js\/woopra\.js/i.// Chrome extensions
    /extensions\//i./^chrome:\/\//i.// Other plugins
    /127\.0\.0\.1:4001\/isrunning/i.// Cacaoweb
    /webappstoolbarba\.texthelp\.com\//i./metrics\.itunes\.apple\.com\.edgesuite\.net\//i,]});Copy the code

Use sampling to filter Transaction events

To prevent certain transactions from being reported to Sentry, use the tracesSampler configuration option, which allows you to provide a function to evaluate the current transaction and remove it if it is not what you want. (It also allows you to sample different transactions at different sampling rates.)

Note: The tracesSampler and tracesSampleRate configuration options are mutually exclusive. If you define a tracesSampler to filter out certain transactions, you must also handle the case of unfiltered transactions by returning the rate at which you want to sample them.

In its simplest form, just for filtering transactions, it looks like this:

Sentry.init({
  // ...

  tracesSampler: samplingContext= > {
    if ("...") {
      // Drop this transaction, by setting its sample rate to 0%
      return 0;
    } else {
      // Default sample rate for all others (replaces tracesSampleRate)
      return 0.1; }}; });Copy the code

Close and Clear

The default behavior of most SDKS is to send events asynchronously in the background over the network. This means that some events may be lost if the application is unexpectedly shut down. The SDK provides a mechanism to handle this situation.

The close method optionally accepts a timeout in milliseconds and returns a promise that will resolve if all pending events are flushed or timeout takes effect.

Sentry.close(2000).then(function() {
  // perform something after close
});
Copy the code

After calling close, the current client can no longer be used. It is important to call close only immediately before closing the application.

Alternatively, the flush method flushes the event queue while leaving the client enabled for continued use.

The sampling

Adding Sentry to your application gives you a lot of valuable information about errors and performance that you would otherwise not have access to. A lot of information is good – as long as it’s the right information and in a reasonable amount.

Sampling Error events

To send a representative sample of errors to Sentry, set the sampleRate option in your SDK configuration to a number between 0 (0% of errors sent) and 1 (100% of errors sent). This is a static ratio, and it also applies to all errors. For example, to sample 25% of errors:

Sentry.init({ sampleRate: 0.25 });
Copy the code

Changing the error sampling rate requires redeployment. In addition, setting the SDK sampling rate limits visibility to the event source. Setting a rate limit for your project (discarding events only when the volume is high) may be more appropriate for your needs.

Sampled Transaction event

We recommend sampling your transaction for two reasons:

  1. Capturing a single trace involves minimal overhead, but capturing every page load or every API request can add unnecessary load to your system.
  2. Enabling sampling allows you to better manage the number of events sent to Sentry, so you can customize your number to your organization’s needs.

The goal of selecting a sampling rate is to strike a balance between performance and quantity issues and data accuracy. You don’t want to collect too much data, but you want to collect enough data to draw meaningful conclusions. If you are unsure what rate to choose, start with a low value and gradually increase it as you learn more about traffic patterns and traffic.

Configure the Transaction sampling rate

The Sentry SDK has two configuration options to control the amount of transactions sent to Sentry, allowing you to get a representative sample:

  1. Uniform sampling rate (tracesSampleRate) :
  • Provide a uniform cross section of transactions, no matter where or under what circumstances they occur in your application.
  • Using default inheritance (inheritance) and priority (precedence) behavior
  1. Sampling function (tracesSampler) :
  • Different samples at different ratestransaction
  • Filter it out completelytransaction
  • Modify the default priority and inheritance behavior

inheritance: Docs. Sentry. IO/platforms/j…

precedence: Docs. Sentry. IO/platforms/j…

Filters: Docs. Sentry. IO/platforms/j…

Set the uniform sampling rate

To do this, set the tracesSampleRate option in sentry.init () to a number between 0 and 1. When this option is set, each transaction created has that percentage chance of being sent to Sentry. (So, for example, if you set tracesSampleRate to 0.2, about 20% of transactions will be logged and sent.) It looks something like this:

Sentry.init({
  // ...

  tracesSampleRate: 0.2});Copy the code
Set the sampling function

To use the sampling function, set the tracesSampler option in sentry.init () to a function that will take the samplingContext object and return a sampling rate between 0 and 1. Such as:

Sentry.init({
  // ...

  tracesSampler: samplingContext= > {
    // Examine provided context data (including parent decision, if any) along
    // with anything in the global namespace to compute the sample rate or
    // sampling decision for this transaction

    if ("...") {
      // These are important - take a big sample
      return 0.5;
    } else if ("...") {
      // These are less important or happen much more frequently - only take 1%
      return 0.01;
    } else if ("...") {
      // These aren't something worth tracking - drop all transactions like this
      return 0;
    } else {
      // Default sample rate
      return 0.1; }}; });Copy the code

For convenience, the function can also return a Boolean value. Returning true is the same as returning 1, and will guarantee that transaction will be sent to Sentry. Returning false is equivalent to returning 0 and guarantees that transaction will not be sent to Sentry.

Sampling Context data

Context data is sampled by default

The information contained in the SamplingContext object passed to tracesSampler during a transaction varies by platform and integration.

For a browser-based SDK, it includes at least the following:

// contents of `samplingContext`
{
  transactionContext: {
    name: string; // human-readable identifier, like "GET /users"
    op: string; // short description of transaction type, like "pageload"
  }
  parentSampled: boolean; // if this transaction has a parent, its sampling decision
  location: Location | WorkerLocation; // the window.location or self.location object.// custom context as passed to `startTransaction`
}
Copy the code
Custom sampling Context data

When creating a transaction using custom detection, you can add data to the samplesContext by passing it to startTransaction as an optional second parameter. This is useful if you want the sampler to have access to some data, but you don’t want to attach it to a transaction as a tag or data, such as sensitive information or information that is too large to be sent with a transaction. Such as:

Sentry.startTransaction(
  {
    // `transactionContext` - will be recorded on transaction
    name: 'Search from navbar'.op: 'search'.tags: {
      testGroup: 'A3'.treatmentName: 'eager load',}},// `customSamplingContext` - won't be recorded
  {
    // PII
    userId: '12312012'.// too big to send
    resultsFromLastSearch: {... }});Copy the code

inheritance

Regardless of the sampling decision for a transaction, that decision is passed on to its subspans, and from there to any transactions they subsequently cause in other services. (For more information on how propagation is done, see Connect Services.)

  • Connecting Services: Docs. Sentry. IO/platforms/j…

If the transaction currently being created is one of those subsequent transactions (in other words, if it has a parent), the upstream (parent) sampling decision will always be included in the sampling context data so that your tracesSampler can choose whether and when to inherit the decision. (In most cases, inheritance is the right choice to avoid partial trace traces.)

In some SDKS, for convenience, the tracesSampler function can return a Boolean so that the parent decision can be returned directly if this is the desired behavior.

tracesSampler: samplingContext= > {
  // always inherit
  if(samplingContext.parentSampled ! = =undefined) {
    return samplingContext.parentSampled
  }

  ...
  // rest of sampling logic here
}
Copy the code

If you use tracesSampleRate instead of tracesSampler, the decision will always be inherited.

Forced sampling decision

You can also choose to pass the sampling decision directly to the Transaction constructor (note, not in the customSamplingContext object) if you know at transaction creation time whether or not to send the Transaction to the Sentry. If you do this, transaction will not be subject to tracesSampleRate and will not run tracesSampler, so you can count on passing decisions not to be overridden.

Sentry.startTransaction({
  name: "Search from navbar".sampled: true});Copy the code

priority

Transaction ends the sampling decision in a number of ways.

  • According to thetracesSampleRateSet the static sampling rate for random sampling
  • According to thetracesSamplerThe sampling function returns the sampling rate for random sampling
  • tracesSamplerAbsolute decision returned (100%Opportunities or0%Chance)
  • iftransactionThere’s a parent that inherits its sampling decisions
  • Absolute decisions are passed tostartTransaction

When it is possible for more than one to come into play, the following priority rules apply:

  1. If you pass the sampling decision tostartTransaction(see the forced sampling decision above), that decision will be used regardless of anything else
  2. If I definetracesSampler, its decision will be used. It can choose to retain or ignore any parent sampling decisions, or use the sampling context data to make its own decisions or fortransactionSelect the sampling rate.
  3. If not definedtracesSampler, but if a parent sampling decision exists, the parent sampling decision will be used.
  4. If not definedtracesSamplerWill be used if there is no parent sampling decisiontracesSampleRate.

Sentry Testkit

When building tests for your application, you want to assert that correct flow-tracking or errors are being sent to Sentry, but not really to the Sentry server. This way you won’t flood the Sentry with error reports during test runs or other CI operations.

Note: Sentry partner Wix maintains Sentry Testkit.

  • Wix:Wix. Making. IO/sentry – test…

Sentry Testkit is a Sentry plug-in that allows you to intercept a Sentry report and further examine the data being sent. It enables Sentry to work natively in your application, and by overriding the default Sentry’s transport mechanism, reports are not actually sent, but logged locally to memory. This way, you can later retrieve the recorded reports for your own use, validation, or any other use you may have in your local development/test environment.

Sentry Testkit: Wix. Making. IO/sentry – test…

The installation

npm install sentry-testkit --save-dev
Copy the code
Use it in tests
const sentryTestkit = require("sentry-testkit");

const { testkit, sentryTransport } = sentryTestkit();

// initialize your Sentry instance with sentryTransport
Sentry.init({
  dsn: "https://[email protected]/0".transport: sentryTransport,
  / /... other configurations
});

// then run any scenario that should call Sentry.catchException(...)

expect(testkit.reports()).toHaveLength(1);
const report = testkit.reports()[0];
expect(report).toHaveProperty(/ *... * /);
Copy the code

You can also see more examples of use in the testing section of the Sentry-TestKit repository.

testing section: Github.com/wix/sentry-…

Testkit API

Sentry Testkit consists of a very simple and straightforward API. See the full API description and documentation in Sentry Testkit Docs.

Sentry Testkit Docs: Wix. Making. IO/sentry – test…

usage

Sentry’s SDK hooks into your runtime environment and automatically reports errors, uncaught exceptions and unhandled rejections, and other types of errors, depending on the platform.

Key terms:

  • eventIs toSentryAn instance of sending data. Typically, this data is an error (error) or exception (exception).
  • issueIt’s a similar set of events.
  • The report of the incident is calledCapture (capturing). When an event is captured, it is sent toSentry.

The most common form of catching is catching errors. What can be caught as an error varies from platform to platform. In general, if you have something that looks like an exception, it can be caught. For some SDKS, you can also omit the captureException argument, and Sentry will attempt to catch the current exception. It is also useful for manually reporting errors or messages to Sentry.

When you capture an event, you can also record the breadcrumbs that caused the event. Breadcrumbs are different from events: they do not create events in Sentry, but are buffered until the next event is sent. Learn more about breadcrumbs in our breadcrumbs document.

breadcrumbs: Docs. Sentry. IO/platforms/j…

Capture the Errors

By including and configuring Sentry, our React SDK automatically appends global handlers to catch uncaught exceptions and unhandled promise rejections, as described in the official ECMAScript 6 standard. You can manually hook into each event handler by changing the onunHandledrejection option to false in the GlobalHandlers integration, This default behavior is then disabled directly by calling sentry. captureException or sentry. captureMessage.

You can pass an Error object to captureException() to capture it as an event. Non-error objects and strings can also be passed, but note that the stack trace can be lost by resulting events in Sentry.

import * as Sentry from "@sentry/react";

try {
  aFunctionThatMightFail();
} catch (err) {
  Sentry.captureException(err);
}
Copy the code

To capture the Messages

Another common operation is to catch naked messages. A message is a text message that should be sent to Sentry. Messages are usually not sent, but they are useful for some teams.

Sentry.captureMessage("Something went wrong");
Copy the code

Set the Level

Levels – similar to log levels – are usually added by default based on integration. You can also override it in an event.

To set the out-of-scope level, you can call captureMessage() for each event:

Sentry.captureMessage("this is a debug message"."debug");
Copy the code

To set the level in scope, you can call setLevel() :

Sentry.configureScope(function(scope) {
  scope.setLevel(Sentry.Severity.Warning);
});
Copy the code

Or each event:

Sentry.withScope(function(scope) {
  scope.setLevel("info");
  Sentry.captureException("info");
});
Copy the code

The SDK fingerprint

Every incident has a fingerprint. Events with the same fingerprint are grouped into an issue.

By default, Sentry runs a built-in grouping algorithm to generate fingerprints based on the information available in the event, such as stacktrace, exception exception, and message. To extend the default grouping behavior or change it completely, you can use a combination of the following options:

  1. In yourSDKIn the useSDKFingerprint identification, as described below
  2. In your project, use fingerprint rules or stack trace rules
    • Fingerprint Rules: https://docs.sentry.io/product/data-management-settings/event-grouping/fingerprint-rules/
    • The Stack Trace Rules: https://docs.sentry.io/product/data-management-settings/event-grouping/stack-trace-rules/

In the supported SDKS, you can override the default grouping of Sentry, which passes fingerprint attributes as an array of strings. The length of the fingerprint array is unlimited. This is similar to the fingerprint rule functionality, which is always available to achieve similar results.

  • Fingerprint - rules: https://docs.sentry.io/product/data-management-settings/event-grouping/fingerprint-rules/

Basic example

In the most basic case, pass values directly:

function makeRequest(method, path, options) {
  return fetch(method, path, options).catch(function(err) {
    Sentry.withScope(function(scope) {
      // group errors together based on their request and response
      scope.setFingerprint([method, path, String(err.statusCode)]);
      Sentry.captureException(err);
    });
  });
}
Copy the code

You can use variable substitution to populate dynamic values into a fingerprint that is normally computed on the server. For example, you can add the value {{default}} to add the entire normally generated grouping hash to the fingerprint. These values are the same as server-side fingerprint identification. For more information, see:

Variables: Docs. Sentry. IO/product/dat…

Group errors with greater granularity

Your application queries a remote Procedure Call Model (RPC) interface or an external application programming interface (API) service, so the stack trace is usually the same (even if the outgoing requests are very different).

The following example further breaks down the default group (represented by {{default}}) that Sentry will create, taking into account some properties of the error object:

class MyRPCError extends Error {
  constructor(message, functionName, errorCode) {
    super(message);

    // The name of the RPC function that was called (e.g. "getAllBlogArticles")
    this.functionName = functionName;

    // For example a HTTP status code returned by the server.
    this.errorCode = errorCode; } } Sentry.init({ ... .beforeSend: function(event, hint) {
    const exception = hint.originalException;

    if (exception instanceof MyRPCError) {
      event.fingerprint = [
        '{{ default }}'.String(exception.functionName),
        String(exception.errorCode)
      ];
    }

    returnevent; }});Copy the code

Further grouping errors

Common errors (such as database connection errors) have many different stack traces and will never be combined.

The following example will completely override the grouping of sentries by omitting {{default}} from the array:

class DatabaseConnectionError extends Error {} Sentry.init({ ... .beforeSend: function(event, hint) {
    const exception = hint.originalException;

    if (exception instanceof DatabaseConnectionError) {
      event.fingerprint = ['database-connection-error'];
    }

    returnevent; }});Copy the code

Source Maps

To generate the Source Maps

Most modern JavaScript compilers support Source Maps. The following is a description of some common tools.

We recommend using Sentry’s Webpack plug-in to configure Source Maps and upload them automatically during the build process.

sentry-webpack-plugin: Github.com/getsentry/s…

source-map-support

To rely on Sentry’s Source Map parsing, your code cannot use the source-map-support package. This package overrides the captured stack trace in a way that prevents our processor from parsing it properly.

The source – the map – support:www.npmjs.com/package/sou…

Webpack

Sentry provides a handy Webpack plug-in that configures Source maps and automatically uploads them to Sentry.

To use the plug-in, you first need to install it:

npm install --save-dev @sentry/webpack-plugin
// or
yarn add --dev @sentry/webpack-plugin
Copy the code

Then, configure it webpack.config.js:

const SentryWebpackPlugin = require("@sentry/webpack-plugin");

module.exports = {
  // other webpack configuration
  devtool: 'source-map'.plugins: [
    new SentryWebpackPlugin({
      // sentry-cli configuration - can also be done directly through sentry-cli
      // see https://docs.sentry.io/product/cli/configuration/ for details
      authToken: process.env.SENTRY_AUTH_TOKEN,
      org: "example-org".project: "example-project".release: process.env.SENTRY_RELEASE,

      // other SentryWebpackPlugin configuration
      include: ".".ignore: ["node_modules"."webpack.config.js"],}),]};Copy the code

In addition, the Webpack plug-in automatically sets window.sentry_release, so your sentry.init call does not need to include a release value.

Set the Webpack plug-in to run last; Otherwise, the source Maps the plug-in receives may not be final.

Advanced usage

If you prefer to manually upload source maps, configure Webpack to export source Maps:

module.exports = {
  devtool: 'source-map'.output: {
    // Make maps auto-detectable by sentry-cli
    filename: "[name].js".sourceMapFilename: "[name].js.map".// Other `output` configuration
  },
  // Other webpack configuration
};
Copy the code

If you use the SourceMapDevToolPlugin for more fine-grained control over source Map generation, turn off noSources so that Sentry can display the correct source context in the event stack trace.

SourceMapDevToolPlugin:Webpack.js.org/plugins/sou…

Rollup

You can configure Rollup to generate source maps, and then you can upload source maps using sentry-CLI:

  • A Rollup:rollupjs.org/
  • The upload using sentry – the cli:Docs. Sentry. IO/product/cli…
export default {
  entry: "./src/app.js".output: {
    file: "bundle.js".format: "cjs".sourceMap: true,}};Copy the code

SystemJS

SystemJS can be configured to output source maps, and then you can upload source maps using sentry-cli:

builder.bundle("src/app.js"."dist/app.min.js", {
  minify: true.sourceMaps: true.sourceMapContents: true});Copy the code

This sample configuration inlines your original, unconverted source code into the generated Source Map file. Sentry requires the Source Map and your original source file to perform the reverse conversion. If you choose not to inline the source files, you must make these source files available to Sentry in addition to the Source Map (see below).

  • SystemJS:Github.com/systemjs/bu…
  • The upload using sentry – the cli:Docs. Sentry. IO/product/cli…

TypeScript

The TypeScript compiler outputs source maps, which you can then upload using sentry-CLI.

Configure the sourceRoot attribute to/to remove the build path prefix from the generated source code reference. This allows Sentry to match source files relative to your source root folder:

{
  "compilerOptions": {
    "sourceMap": true."inlineSources": true."sourceRoot": "/"}}Copy the code

UglifyJS

We strongly recommend that you use a more advanced packer (or translator), as UglifyJS configurations can become very complex and difficult to achieve the desired results.

UglifyJS can be configured to output source maps, which you can then upload using sentry-CLI:

uglifyjs app.js \
  -o app.min.js.map \
  --source-map url=app.min.js.map,includeSources
Copy the code

UglifyJS:Github.com/mishoo/Ugli…

Upload the Source Maps

Webpack

Sentry uses Releases to match the correct source maps to your event. The Release API is designed to allow you to store source files (and source maps) in your Sentry.

You can do this with the help of our Webpack plug-in, which uses our Sentry CLI internally.

  1. From your[Account] > API keysCreate a new authentication token
  2. Make sure you on"Scopes"Choose theproject:write
  3. usenpmThe installation@sentry/webpack-plugin
  4. Create with the necessary configuration.sentryclircDocuments, as described on this page
  5. Update yourwebpack.config.js
const SentryPlugin = require("@sentry/webpack-plugin");

module.exports = {
  // ... other config above ...
  plugins: [
    new SentryPlugin({
      release: process.env.RELEASE,
      include: "./dist",})]};Copy the code

Use our Sentry Webpack plug-in documentation to learn more about further configuration of the plug-in. Sentry-webpack-plugin:github.com/getsentry/s…

In addition, you need to configure the client to send release:

Sentry.init({
  dsn: "https://[email protected]/0".release: process.env.RELEASE,
});
Copy the code

You don’t have to use the RELEASE environment variable. You can provide them in any form as long as the version you upload matches the version of the SDK’s init call.

Releases the API:Docs. Sentry. IO/API/release…

Sentry CLI

Upload Source Maps using sentry-cli

When uploading Source maps using Sentry-CLI, you need to set up the build system to create releases and upload various source files corresponding to that version. To have Sentry decode your stack trace, also provide:

  • To deploy the file (in other words, yoursCompile/compression/packaging (transpilation/minification/bundling)The result of a process; For example,app.min.js)
  • The correspondingsource maps

If the Source Map file does not contain your original source content, you must also provide the original source file. If the source file is missing, Sentry CLI will attempt to automatically embed the source into your Source Maps.

Sentry uses Releases to match the correct source maps to your event. To create a new version, run the following command (for example, during release) :

The releases:Docs. Sentry. IO/product/rel…

sentry-cli releases new <release_name>
Copy the code

The release name must be unique in your organization and match the Release option in your SDK initialization code. Then, use the upload-sourcemaps command to scan the sourcemaps in the folder, process them, and upload them to Sentry.

sentry-cli releases files <release_name> upload-sourcemaps /path/to/files
Copy the code

You can find the artifacts uploaded to Sentry by navigating to [Project] > Project Settings > Source Maps.

This will upload all files ending in.js and.map to the specified version (release). If you want to change these extensions — for example, upload typescript source files — use the –ext option:

sentry-cli releases files <release_name> upload-sourcemaps --ext ts --ext map /path/to/files
Copy the code

As of now, this version is in draft status (” unreleased “). Once all source maps have been uploaded and your application has been successfully published, use the following command to complete release:

sentry-cli releases finalize <release_name>
Copy the code

For convenience, you can pass the — Finalize flag to the new command, which will immediately complete release.

See our Sentry-CLI documentation for more information.

  • Sentry – the cli:Docs. Sentry. IO/product/cli…

It is not uncommon for Web applications to be accessible from multiple sources. See our documentation on multiple sources to see how to handle this problem.

  • Multiple origins:Docs. Sentry. IO/platforms/j…

Public trust

The most reliable way to provide Source maps to Sentry is to upload them, as it reduces network traffic and ensures that the correct version of the code and source mapping will be used.

By default, Sentry will look for the Source Map directive in the JavaScript file you compile. These instructions are on the last line and have the following format:

//# sourceMappingURL=<url>
Copy the code

When Sentry encounters such an instruction, it parses the Source Map URL relative to the source file it is in and tries an HTTP request to retrieve it.

For example, if you have a compressed JavaScript files at http://example.org/js/app.min.js, and in the last line of the file, you can find the following instructions:

//# sourceMappingURL=app.js.map
Copy the code

Sentry will try to get the app from http://example.org/js/app.js.map. Js. The map.

Alternatively, during source Map generation, you can specify the fully qualified URL where the Source Map resides:

//# sourceMappingURL=http://example.org/js/app.js.map
Copy the code

While providing Source Maps to Sentry from your server is the most natural integration, it is not always desirable:

  • Sentry may not always be able to access your server.
  • If you are not inasset URLA version mismatch may exist
  • The additional delay may mean that the source mapping is not suitable for all errors.

For these reasons, it’s best to upload Source Maps to Sentry beforehand (see below).

Work behind a firewall

While the recommended solution is to upload your source artifacts (packaged translated code) to the Sentry, there are times when you need to allow communication from the internal IP of the Sentry. For more information about Sentry Public IP, see:

  • IP Ranges:Docs. Sentry. IO/product/SEC…
Secure access to Source Maps

If you want to keep Source Maps private and choose not to upload source Maps directly to Sentry, you can enable the “Security Token” option in the project Settings.

This will cause outbound requests from Sentry’s server url from your “Allowed Domains” to attach the HTTP header x-Sentry-token header:

GET /assets/bundle.min.js
X-Sentry-Token: {token}
Copy the code

The token is a security value that you define in your project Settings. You can then configure your Web server to allow access to your Source Maps while the header/ Token pair exists. You can also override the default header name (X-sentry-token) and use HTTP Basic Authentication, for example by passing Authorization: Basic {encoded_password}.

Multiple Origin

It is not uncommon for Web applications to be accessible from multiple sources. Such as:

  • The website can be downloadedhttpshttprun
  • Geolocation urls: for examplehttps://us.example.com,https://eu.example.com
  • Multiple staticCDN, such as:https://static1.example.com,https://static2.example.com
  • Customer specific domains/subdomains

In this case, the same JavaScript and source map files may be located in two or more different sources. In this case, we recommend using our special tilde (~) prefix on paths.

For example, if you have the following:

  • static1.example.com/js/app.js
  • static2.example.com/js/app.js

You can upload using the URL ~/js/app.js. This tells Sentry to ignore the domain and use the artifact for any source.

In addition, you can upload the same file with multiple names. Sentry deduplicates these under the hood.

The ~ prefix tells Sentry that for a given URL, any combination of protocol and hostname with a path of /js/app.js should use this artifact.

Verify that the file

Making sure source Maps themselves work and are uploaded correctly can be challenging. To address this issue, we maintain an online validation tool that can be used to test your Source map: sourcemaps.io against your managed source.

  • sourcemaps.io/

Additionally, you can use the –validate flag when uploading source maps using sentry-CLI, which attempts to parse the source map locally and find references. Note that the validation flag is known to indicate failure when set up correctly (the validation tool will indicate failure if you refer to external Source maps).

In addition to the validation steps, you can also check these:

  • Make sure your file’s URL prefix is correct. It’s easy to go wrong.
  • Match the uploaded compressed filesource maps.
  • Make sure that your zip file on the server actually references your file.

Best practices

A simple setup

In this simple project, the minified/transpiled files and their source maps are in the same directory:

├ ─ ─ the build / │ ├ ─ ─ worker. Js │ ├ ─ ─ worker. Js. Map │ ├ ─ ─ app. Js │ ├ ─ ─ app. Js. Map │ ├ ─ ─ index. The HTML ├ ─ ─ package. The json ├ ─ ─ Public / │ ├─ ├─ ├─ class.org.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txtCopy the code

For this project, we can use a simple Sentry configuration:

const SentryWebpackPlugin = require("@sentry/webpack-plugin");
// ...
plugins: [
  new SentryWebpackPlugin({
    authToken: process.env.SENTRY_AUTH_TOKEN,
    org: "example-org".project: "example-project".include: "build".configFile: "sentry.properties".release: process.env.SENTRY_RELEASE,
  }),
],
// ...
Copy the code

We recommend using the Webpack plug-in to integrate Source Maps into Sentry. If you don’t use Webpack in your project, you can use the Sentry CLI.

Consistent version

To have Sentry associate the error stack trace with your Source Maps, define your version number as either the Webpack plug-in option or the Sentry CLI parameter (whichever you use). If you use the Sentry CLI, you should also define the same version number in the sentry.init () call. The easiest way to ensure version number consistency is to set it to an environment variable in your project:

# ...
SENTRY_RELEASE="1.2.3"
# ...
Copy the code

Then, if you use the Sentry-webpack-plugin:

// ...
new SentryWebpackPlugin({
  // ... other options
  release: process.env.SENTRY_RELEASE,
});
// ...
Copy the code

Or, if you are using the Sentry CLI:

sh sentry-cli releases new "$SENTRY_RELEASE" sentry-cli releases files "$SENTRY_RELEASE" upload-sourcemaps /path/to/sourcemaps

// ...
Sentry.init({
  // ... other options
  release: process.env.SENTRY_RELEASE,
});
// ...
Copy the code

Correct Source Paths

The file names for your release artifacts (bundle files and source maps) should match the path reported in the stack trace. You can use the upload configuration to adjust the file name. Both the Webpack plug-in and Sentry CLI have the same options; Here’s a look at source Maps. You can also use our RewriteFrames integration to adjust paths within the stack trace.

Depending on your setup, you may need to configure Source Maps differently in your development and production environments because the paths in the stack trace may be different.

Webpack and Sentry CLI options

These options and examples will help you integrate your Source Maps.

include

This option accepts one or more paths to recursively scan source and *.map files. Such as:

  1. Include the location of your translator/binder output file:
  • include: './app/.next'
  • include: './build'
  1. Includes from multiple folders:
  • Includes: ['./ SRC ', './lib']
  1. Recursively search the entire project:
  • include: '.'

rewrite

It allows you to rewrite the matched source maps so that if possible, the index map flattens and inlines missing sources. The default is true.

This option should be enabled to make stripPrefix and stripCommonPrefix work.

urlPrefix

This option adds a common prefix to the beginning of all file names. Defaults to ~ /, this is a wildcard to match any scheme and the hostname (http://my.web.site/path/to/script.js http://my.web.site/).

This option is useful when the entry point of an application (typically index.html on the browser side and index.js on Node) is one or more levels above the source/source mapping file, as shown in the following example:

├ ─ ─ the build / │ ├ ─ ─ index. The HTML │ ├ ─ ─ the static / │ │ ├ ─ ─ app. Js │ │ ├ ─ ─ app. Js. The mapCopy the code

In this case, follow the following example to configure:

// ...
new SentryWebpackPlugin({
  // ...
  include: "build/static/",
  urlPrefix: "~/static/"
  // ...
}),
// ...
Copy the code

stripPrefix

This option removes the given prefix from the filename referenced in sourcemap (for example, in Sources Entry). This is useful when you need to trim extra prefixes that the Bundler/Development server may add to the file name, such as webpack://_N_E/.

Note that using the stripPrefix option does not change the name of the uploaded file. When you use the parent folder of the target file as an unwanted prefix, include the section to be removed in the path/to/sourcemaps that contains the Webpack plug-in option or is passed to sentry-CLI. For example, if your file is stored in./build/static/js/ and you have include: “build” in the Webpack plugin configuration, your file will be uploaded with a name similar to ~/static/js/bundle.js. If you update your configuration include: “build/static/js”, your files will be uploaded as ~/bundle.js (etc.).

Adjust the frame (Frames)

Alternatively, you can use Sentry’s RewriteFrames integration to fine-tune paths within the stack trace.

import { RewriteFrames } from "@sentry/integrations";

Sentry.init({
  dsn: "https://[email protected]/0".integrations: [
    new RewriteFrames({
      // ... options})]});Copy the code

Troubleshoot Source Maps

Source Maps are sometimes hard to get started. If you encounter problems:

Verify that a release is configured in your SDK

To locate and apply the uploaded Source maps, you need to create a release through the CLI or API (and the correct artifact uploaded with it), and you need to specify the name of the newly created release in your SDK configuration.

To verify this, open the issue from Sentry UI and check that release is configured. If “Not configured” or “N/A” is displayed next to “Release” on the right side of the screen (or if you don’t see A Release tag in the tag list), go back and flag your error. If set correctly, you will see “Release: my_example_release”.

Verify that artifacts have been uploaded

Once you have configured your release properly and flagged problems, you can navigate to [Project] » Project Settings » Source Maps to find the artifacts uploaded to Sentry.

Also, make sure all necessary documents are available. To make the Sentry de-Minify stack trace, you must provide both the Minify file (for example app.min.js) and the corresponding source map. If the Source Map file does not contain your original source content, you must provide the original source file separately. Alternatively, Sentry-CLI will automatically embed the source code (if missing) into your Source Maps.

validationsourceMappingURLIf there is a

Some CDNS automatically remove comments from static files, including JavaScript files. This may cause the sourceMappingURL directive to be removed from the JavaScript file because it is treated as an annotation. For example, CloudFlare has a feature called Auto-Minify that, if enabled, removes the sourceMappingURL.

  • Auto – Minify:Blog.cloudflare.com/an-all-new-…

Double check that the final JavaScript file you deploy has the sourceMappingURL.

Alternatively, you can set the SourceMap HTTP header instead of the sourceMappingURL on minify’s file. If this header exists, Sentry will use it to discover the location of the Source Map.

Verify that the Artifact release values match those configured in your SDK

Whenever you use the distribution identifier (dist configuration option in the SDK), the same value must be used during source Map uploads. Conversely, if your Source Map uploads using dist values, you must set the same values in your SDK. To add dist values to your uploaded Source maps, use the –dist flag with the sentry-cli or dist option and @sentry/webpack-plugin. To set the dist value in the SDK, use the dist option in sentry.init ().

To verify that the distribution Settings in the SDK are correct, open an issue in Sentry UI and check if the DIST tag exists. For the artifact, go to the Source Maps page in the project Settings, select the Release shown in the event you just checked, and verify that the dist value (in the small oval next to the Upload Time) matches the value on the event.

Verify artifact names withsourceMappingURLValues match

The sourceMappingURL comment in the last line of bundled or minified JavaScript files tells Sentry (or browser) where to find the corresponding Source map. This can be a fully qualified URL, a relative path, or the filename itself. When uploading an artifact to Sentry, you must name the source mapping file using the value that the file resolves to.

That is, if your file looks something like:

// -- end script.min.js
//# sourceMappingURL=script.min.js.map
Copy the code

And hosted on http://example.com/js/script.min.js, then the Sentry will look for the source map file in http://example.com/js/script.min.js.map. Therefore, you must upload an artifact named http://example.com/js/script.min.js.map (or ~ / js/script. Min. Js. The map).

Or, if your file looks something like:

//-- end script.min.js
//# sourceMappingURL=https://example.com/dist/js/script.min.js.map
Copy the code

The artifact you upload should also be named:

https://example.com/dist/js/script.min.js.map (or ~ / dist/js/script. Min. Js. The map).

Finally, if your file looks something like:

//-- end script.min.js
//# sourceMappingURL=.. /maps/script.min.js.map
Copy the code

Then you upload an artifact should be named https://example.com/dist/maps/script.min.js.map (or ~ / dist/maps/script. Min. Js. Map).

Verify that the Artifact name matches the stack trace frame

If you have uploaded source maps but they are not applied to the code in the Sentry problem, look at the JSON of the event and look for the ABS_PATH to see exactly where we are trying to parse the file – for example, http://localhost:8000/scripts/script.js (for each frame in the stack trace, abs_path will appear at a time – with its deminified files match.) . You can find a link to the JSON view at the top of the issue page next to the event date. The uploaded artifact name must match these values.

If you have dynamic values in your path (for example, https://www.site.com/{some_value}/scripts/script.js), you may need to use the rewriteFrames integration to change your ABS_PATH value.

Use the sentry – cli

If your sourceMappingURL annotation looks something like:

// -- end script.min.js (located at http://localhost:8000/scripts/script.min.js)
//# sourceMappingURL=script.min.js.map
Copy the code

An example sentry-cli command for correctly uploading these files looks like this (assuming you are in the /scripts directory, running the Web server from the upper directory, which is why we use the –url-prefix option) :

sentry-cli releases files VERSION upload-sourcemaps . --url-prefix '~/scripts'
Copy the code

This command uploads all JavaScript files in the current directory. The Artifacts page in Sentry should now look like this:

~/scripts/script.js
~/scripts/script.min.js
~/scripts/script.min.js.map
Copy the code

Alternatively, you can specify the file to upload. Such as:

sentry-cli releases files VERSION upload-sourcemaps script.min.js script.min.js.map --url-prefix '~/scripts'
Copy the code

You can also upload it using a fully qualified URL. Such as:

sentry-cli releases files VERSION upload-sourcemaps . --url-prefix 'http://localhost:8000/scripts'
Copy the code
Use the API

You can also upload an artifact using the API.

curl -X POST \
  https://sentry.io/api/0/organizations/ORG_SLUG/releases/VERSION/files/ \
  -H 'Authorization: Bearer AUTH_TOKEN' \
  -H 'content-type: multipart/form-data' \
  -F [email protected] \
  -F 'name=~/scripts/script.min.js.map'
Copy the code
Use ~

~ is used in Sentry to replace scheme and domain.

http://example.com/dist/js/script.js will match the ~ / dist/js/script js or http://example.com/dist/js/script.js

But it does not match ~/script.js.

Verify that the artifact is uploaded before an error occurs

Sentry expects the source code and Source maps in a given release to be uploaded to Sentry before an error occurs in that release.

If you upload an artifact after Sentry captures errors, Sentry will not go back and retroactively apply any source annotations to those errors. Only new errors triggered after the artifact is uploaded are affected.

Verify that your Source Maps are built correctly

We maintain an online validation tool that can be used to test your Source maps: sourcemaps.io against your managed source.

  • sourcemaps.io/

Alternatively, if you upload source maps to Sentry using the Sentry CLI, you can use the –validate command line option to verify that your Source maps are correct.

Verify that your Source Maps work locally

If you find that Sentry does not map filename, row, or column mappings correctly, you should verify that your Source Maps are running locally. To do this, you can use Node.js in conjunction with Mozilla’s Source-Map Library.

  • Github.com/mozilla/sou…

First, install source-Map as the NPM module globally:

npm install -g source-map
Copy the code

Then, write a script to read your Source Map file and test the mapping. Here’s an example:

var fs = require("fs"),
  path = require("path"),
  sourceMap = require("source-map");

// file output by Webpack, Uglify, and so forth
var GENERATED_FILE = path.join("."."app.min.js.map");

// line and column located in your generated file (for example, the source of your error
// from your minified file)
var GENERATED_LINE_AND_COLUMN = { line: 1.column: 1000 };

var rawSourceMap = fs.readFileSync(GENERATED_FILE).toString();
new sourceMap.SourceMapConsumer(rawSourceMap).then(function(smc) {
  var pos = smc.originalPositionFor(GENERATED_LINE_AND_COLUMN);

  // should see something like:
  // { source: 'original.js', line: 57, column: 9, name: 'myfunc' }
  console.log(pos);
});
Copy the code

If you get the same (incorrect) results locally as you get through Sentry, carefully check your Source Map generation configuration.

Verify that your source file is not too large

For a single artifact, Sentry accepts a maximum file size of 40 MB.

Users typically hit this limit because they transfer source files during the interim build phase. For example, after Webpack/Browserify merges all source files, but before minification. If possible, send the original source file.

Verify that the artifact is not gzip

The Sentry API currently only works with source maps and source files uploaded in plain text (UTF-8 encoding). If files are uploaded in a compressed format (such as gzip), they will not be interpreted correctly.

This sometimes happens in build scripts and plug-ins that generate pre-compressed minified files. For example, the Compression plug-in for Webpack. You need to disable such plug-ins and perform compression after the generated Source maps/ Source files are uploaded to Sentry.

  • Github.com/webpack/com…

Verify that the worker shares the same volume as the Web (if running self-hosted Sentry via Docker)

Sentry performs source map calculations in its worker. This means that the worker needs to access the files uploaded via the front end. Check that the Cron worker and web worker can read/write files from the same disk.

troubleshooting

If you need help with Sentry JavaScript SDK Integration, you can read the edge cases documented here.

Debug additional data

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

See the complete documentation on event payloads for more details.

  • Develop. Sentry. Dev/SDK/event – p…

Maximum JSON Payload size

The default value for maxValueLength is 250, but you can adjust this value as needed if your message is longer. Note that not every value is affected by this option.

CORS attributes and headers

To learn about JavaScript exceptions thrown from scripts from different sources, do two things:

  1. addcrossorigin="anonymous"The script properties
 <script src="http://another-domain.com/app.js" crossorigin="anonymous"></script>
Copy the code

The script attribute tells the browser to “anonymously” get the object file. When this file is requested, the browser does not transfer potential user identifying information, such as cookies or HTTP credentials, to the server.

  1. addCross-Origin HTTP header
Access-Control-Allow-Origin: *
Copy the code

Cross-domain Resource sharing (CORS) is a set of apis (mostly HTTP headers) that dictate how files should be downloaded and served across domains.

By setting access-Control-allow-Origin: *, the server indicates to the browser that the file is available from any source. Alternatively, you can limit it to known sources under your control:

 Access-Control-Allow-Origin: https://www.example.com
Copy the code

Most community CDNS have the Access-Control-Allow-Origin header set correctly.

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

 Access-Control-Allow-Origin: *
Copy the code

Unexpected OPTIONS request

If your application starts behaving abnormally due to executing additional OPTIONS requests, it is likely to be a problem with unwanted Sentry-trace request headers, This can happen when you use an overly generic configuration for our Tracing Integration in the browser SDK.

To resolve this issue, change the trackingOrigins option during SDK initialization. For more details, see Automatic detection in our performance monitoring documentation.

  • Docs. Sentry. IO/platforms/j…

instrument.jsThe line number of the Console Log statement

If instrument.js is displayed in your console during debugging, add Sentry to your frame black box Settings, for example: /@sentry/ so that Chrome ignores SDK stack frames while debugging.

  • Blackboxing: docs. Sentry. IO/platforms/j…

Dealing with Ad-blockers

When you use our CDN, AD blocking or script blocking extensions may prevent our SDK from being properly fetched and initialized. Therefore, any calls to the SDK API will fail and may cause unexpected behavior in your application.

In addition, even if the SDK is downloaded and initialized correctly, Sentry endpoints that need to receive captured data may be blocked. This will prevent any error reporting, session health, or performance data from being delivered, making it virtually unavailable in sentry.io.

You can resolve the first issue in any of the above ways. However, endpoint blocking can only be resolved using tunneling.

Using the tunnel option

A tunnel is an HTTP endpoint that acts as a proxy between Sentry and your application. Because you control this server, there is no risk that any requests sent to it will be blocked. When the endpoint is under the same source (although it does not have to work for tunnels), the browser does not treat any request to the endpoint as a third-party request. Therefore, different security measures will be applied to these requests, and AD blockers will not be triggered by default. A quick summary of the process can be found below.

Starting with JavaScript SDK version 6.7.0, you can use the tunnel option to tell the SDK to send events to the configured URL instead of using DSN. This allows the SDK to remove sentry_key from query parameters, which is one of the main reasons that AD blockers prevent sending events in the first place. This option also prevents the SDK from sending precheck requests, which is one of the requirements to send sentry_key in query parameters.

To enable the tunnel option, provide a relative or absolute URL in the sentry.init call. When you use a relative URL, it is relative to the current source, which is the form we recommend. Using relative urls does not trigger pre-checked CORS requests and therefore does not block any events because AD blockers do not treat these events as third-party requests.

Sentry.init({
  dsn: "https://[email protected]/0".tunnel: "/tunnel"});Copy the code

After the configuration is complete, all events are sent to the /tunnel endpoint. However, this solution requires additional configuration on the server, since events now need to be parsed and redirected to Sentry. Here is an example of your server component:


      
// Change $host appropriately if you run your own Sentry instance.
$host = "sentry.io";
// Set $known_project_ids to an array with your Sentry project IDs which you
// want to accept through this proxy.
$known_project_ids = array(  );

$envelope = stream_get_contents(STDIN);
$pieces = explode("\n".$envelope.2);
$header = json_decode($pieces[0].true);
if (isset($header["dsn"]) {$dsn = parse_url($header["dsn"]);
    $project_id = intval(trim($dsn["path"]."/"));
    if (in_array($project_id.$known_project_ids)) {
      $options = array(
        'http'= >array(
            'header'= >"Content-type: application/x-sentry-envelope\r\n".'method'= >'POST'.'content'= >$envelope));echo file_get_contents(
          "https://$host/api/$project_id/envelope/".false,
          stream_context_create($options)); }}Copy the code
// Requires.NET Core 3.1 and C# 9 or higher
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text.Json;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

// Change host appropriately if you run your own Sentry instance.
const string host = "sentry.io";
// Set knownProjectIds to a list with your Sentry project IDs which you
// want to accept through this proxy.
var knownProjectIds = new HashSet<string>() {  };

var client = new HttpClient();
WebHost.CreateDefaultBuilder(args).Configure(a =>
    a.Run(async context =>
    {
        context.Request.EnableBuffering();
        using var reader = new StreamReader(context.Request.Body);
        var header = await reader.ReadLineAsync();
        var headerJson = JsonSerializer.Deserialize<Dictionary<string.object>>(header);
        if (headerJson.TryGetValue("dsn".out var dsnString)
            && Uri.TryCreate(dsnString.ToString(), UriKind.Absolute, out var dsn))
        {
            var projectId = dsn.AbsolutePath.Trim('/');
            if (knownProjectIds.Contains(projectId) && string.Equals(dsn.Host, host, StringComparison.OrdinalIgnoreCase)) {
              context.Request.Body.Position = 0;
              await client.PostAsync($"https://{dsn.Host}/api/{projectId}/envelope/".new StreamContent(context.Request.Body));
            }
        }
    })).Build().Run();
Copy the code

Check out our sample repository for more information.

  • Github.com/getsentry/e…

If your use case is related to the SDK package itself being blocked, any of the following solutions can help you solve the problem.

Use Package directly

The best way to handle script-blocking extensions is to use the SDK package directly through NPM and bundle it with your application. This way, you can ensure that the code always does what you want it to.

The second option is to download the SDK from our CDN and host it yourself. That way, the SDK will still be separate from the rest of your code, but you can be sure it won’t be blocked because it will come from the same source as your site.

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

The curl https://browser.sentry-cdn.com/5.20.1/bundle.min.js - o sentry. Browser. 5.20.1. Min. Js -sCopy the code

Use the JavaScript Proxy API

The last option is to use Proxy protection, which will ensure that your code does not break even if you call our SDK and it is blocked. All browsers except Internet Explorer support Proxy. Also, if the Proxy is not in any of your users’ browsers, it will be quietly skipped, so you don’t have to worry about it breaking anything.

Place this code snippet directly above the

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);
}
Copy the code

If you want to copy and paste code snippets directly, here it is minified:

<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>
Copy the code

Use Client directly

To be able to manage multiple Sentry instances without any conflicts between them, you need to create your own Client. This also helps prevent tracking of any parent application errors if your application is integrated into it. In this example, we use @sentry/browser but it also works for @Sentry /node.

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

const client = new BrowserClient({
  dsn: "https://[email protected]/0"}); client.captureException(new Error("example"));
Copy the code

While the above example should work, some methods, such as configureScope and withScope, are missing on the Client because the Hub is responsible for state management. That’s why it might be easier to create a new Hub and bind clients to it. The result is the same, but you also get state management.

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

const client = new BrowserClient({
  dsn: "https://[email protected]/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");
});
Copy the code

Process integration

Integration is set up on the Client, and if you need to work with multiple clients and hubs, you must also ensure that integration is handled correctly. This is a working example of how to use multiple clients and multiple hubs running global integration.

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://[email protected]/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://[email protected]/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");
  });
});
Copy the code

Third-party Promise library

When you include and configure Sentry, our JavaScript SDK automatically attaches global Handlers to capture uncaught exceptions and unhandled promise rejections. You can manually hook into each event handler by changing the onunHandledrejection option to false in the GlobalHandlers integration, This default behavior is then disabled directly by calling sentry. captureException or sentry. captureMessage.

If you use a third-party library to implement Promise, you may also need to manage your configuration. Also, keep in mind that browsers typically implement security measures to prevent error reporting when serving script files from different sources.

Has “non-error exceptionsNon-Error Exception“Event

If you see the Error message non-error Exception (or Promise rejection) Captured with keys: X, y, z. “, which happens when you a) call sentry.CaptureException () with the Plain Object, and b) throw a Plain Object, Or c) reject a promise with a plain object.

You can view the contents of the non-error object in question in the __serialized__ entry in the Additional Data section.

To better understand these Error events, we recommend finding the location where the Plain Object was passed or thrown to the Sentry based on the contents of the __serialized__ data, and then converting the Plain Object to an Error object.

Supported browsers

Sentry’s JavaScript SDK supports the following browsers:

Android Firefox Chrome IE iPhone Edge Safari
4.4 latest latest IE 10 iOS12 latest latest
5.0 IE 11 iOS13
6.0
7.1
8.1
9.0
10.0

Supports <= IE 11

Prior to 5.7.0, our JavaScript SDK required some polyfills for older browsers such as IE 11 and below. If you are using it, please upgrade to the latest version or add the script tag below before loading our SDK.

<script src="https://polyfill.io/v3/polyfill.min.js? features=Promise%2CObject.assign%2CString.prototype.includes%2CNumber.isNaN"></script>
Copy the code

We need the following polyfill:

  • Promise
  • Object.assign
  • Number.isNaN
  • String.prototype.includes

Also, remember to define a valid HTML DOCType at the top of the HTML page to ensure that IE does not enter compatibility mode.