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
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)
- when
Error Boundary
Should be rendered when an error is caughtSentry User Feedback Widget
.
dialogOptions
(Object)
- Passed to the
Sentry User Feedback Widget
Options. 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 error
React
Elements. It can be practicalReact
Elements (i.e.<Fallback />
), or returnReact
Function of the element. If you provide a function,Sentry
It is invoked with additional information and helper (see the example below).
onError
(Function)
- when
Error Boundary
The function called when an error is encountered. If you want to propagate errors toRedux
Or you want to check for any side effects that might occur due to an error,onError
Very useful.
onUnmount
(Function)
- in
ErrorBoundary componentWillUnmount()
The function called on.
BeforeCapture (Function) * (available for versions 5.20.0 and later)
- Before sending an error to
Sentry
The 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 analyzed
mount
The span of time required.
react.render
- Represents the time span of the parsed component on the page. Only when a transaction occurs
mount
和unmount
This 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 been
mount
Is 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’s
displayName
Property or componentname
Properties.
includeRender
(boolean)
- Whether it should be
Profiler
createreact.render
Span. The default istrue
.
includeUpdates
(boolean)
react.update
Spans should be driven byProfiler
To create. The default istrue
. For components that will undergo multiple re-renders, such as text inputtext input
Component), we recommend setting this property tofalse
Because of the generatedspan
It 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 | root Is 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.0
And 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:
- 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
- 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 than
200
A character
This value can be arbitrary, but we recommend any of the following naming strategies:
- Semantic versioning:
package@version
或package@version+build
(e.g.,[email protected]+ 1234).package
是project/app
Unique identifier ofiOS
On theCFBundleIdentifier
.Android
On thepackageName
)version
Is similar to thesemver
The structure of the<major>.<minor? >.<patch? >.<revision? >-<prerelease? >
(iOS
On theCFBundleShortVersionString
.Android
On theversionName
)build
Is to identifyapp
Number of iterations (iOS
On theCFBundleVersion
.Android
On theversionCode
)
- Commit SHA:If you use
DVCS
, we recommend usingIdentifies a hash
(e.g.,commit SHA
.da39a3ee5e6b4b0d3255bfef95601890afd80709
). You can makeSentry CLI
usesentry-clireleases proposal-version
This 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:
- if
unhandled error
或unhandled promise rejection
Bubble to the global handler and crash. - if
SDK
An 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:
beforeSend / beforeBreadcrumb
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:
- Capturing a single trace involves minimal overhead, but capturing every page load or every API request can add unnecessary load to your system.
- 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:
- 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
- Sampling function (
tracesSampler
) :
- Different samples at different rates
transaction
- Filter it out completely
transaction
- 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 the
tracesSampleRate
Set the static sampling rate for random sampling - According to the
tracesSampler
The sampling function returns the sampling rate for random sampling tracesSampler
Absolute decision returned (100%
Opportunities or0%
Chance)- if
transaction
There’s a parent that inherits its sampling decisions - Absolute decisions are passed to
startTransaction
When it is possible for more than one to come into play, the following priority rules apply:
- If you pass the sampling decision to
startTransaction
(see the forced sampling decision above), that decision will be used regardless of anything else - If I define
tracesSampler
, 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 fortransaction
Select the sampling rate. - If not defined
tracesSampler
, but if a parent sampling decision exists, the parent sampling decision will be used. - If not defined
tracesSampler
Will 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:
event
Is toSentry
An instance of sending data. Typically, this data is an error (error
) or exception (exception
).issue
It’s a similar set of events.- The report of the incident is called
Capture (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:
- In your
SDK
In the useSDK
Fingerprint identification, as described below - 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.
- From your
[Account] > API keys
Create a new authentication token - Make sure you on
"Scopes"
Choose theproject:write
- use
npm
The installation@sentry/webpack-plugin
- Create with the necessary configuration
.sentryclirc
Documents, as described on this page - Update your
webpack.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, yours
Compile/compression/packaging (transpilation/minification/bundling)
The result of a process; For example,app.min.js
) - The corresponding
source 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 in
asset URL
A 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 downloaded
https
和http
run - Geolocation urls: for example
https://us.example.com
,https://eu.example.com
- Multiple static
CDN
, 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 file
source 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:
- Include the location of your translator/binder output file:
include: './app/.next'
include: './build'
- Includes from multiple folders:
Includes: ['./ SRC ', './lib']
- 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.
validationsourceMappingURL
If 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 withsourceMappingURL
Values 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:
- add
crossorigin="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.
- add
Cross-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.js
The 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.