@sentry/browser
Advanced tools
Comparing version 0.4.0-beta.4 to 0.4.0-beta.5
@@ -1,1 +0,2 @@ | ||
export { SentryBrowser, BrowserOptions as SentryBrowserOptions } from './lib/browser'; | ||
export * from './lib/backend'; | ||
export * from './lib/frontend'; |
@@ -6,2 +6,4 @@ 'use strict'; | ||
var RavenJS = require('raven-js'); | ||
var core = require('@sentry/core'); | ||
var utils = require('@sentry/utils'); | ||
@@ -22,3 +24,22 @@ /*! ***************************************************************************** | ||
***************************************************************************** */ | ||
/* global Reflect, Promise */ | ||
var extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
function __extends(d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
} | ||
var __assign = Object.assign || function __assign(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
function __awaiter(thisArg, _arguments, P, generator) { | ||
@@ -61,140 +82,269 @@ return new (P || (P = Promise))(function (resolve, reject) { | ||
function __read(o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
} | ||
function __spread() { | ||
for (var ar = [], i = 0; i < arguments.length; i++) | ||
ar = ar.concat(__read(arguments[i])); | ||
return ar; | ||
} | ||
/** Casted raven instance with access to internal functions. */ | ||
// tslint:disable-next-line:variable-name | ||
var Raven = RavenJS; | ||
var sendRavenEvent = Raven._sendProcessedPayload; | ||
var SentryBrowser = /** @class */ (function () { | ||
function SentryBrowser(client, options) { | ||
if (options === void 0) { options = {}; } | ||
this.client = client; | ||
this.options = options; | ||
this.capturing = false; | ||
/** Original raven send function. */ | ||
var sendRavenEvent = Raven._sendProcessedPayload.bind(Raven); | ||
/** | ||
* Normalizes the event so it is consistent with our domain interface. | ||
* @param event | ||
* @returns | ||
*/ | ||
function normalizeRavenEvent(event) { | ||
var ex = (event.exception || {}); | ||
if (ex && ex.values) { | ||
event.exception = ex.values; | ||
} | ||
SentryBrowser.prototype.install = function () { | ||
Raven.config(this.client.dsn.toString(), this.options).install(); | ||
// Hook into Raven's breadcrumb mechanism. This allows us to intercept | ||
// both breadcrumbs created internally by Raven and pass them to the | ||
// Client first, before actually capturing them. | ||
Raven.setBreadcrumbCallback(this.interceptRavenBreadcrumb.bind(this)); | ||
// Hook into Raven's internal event sending mechanism. This allows us to | ||
// intercept events generated by Raven in the same way as events created | ||
// via `SentryBrowser.captureException`. In both cases, we call | ||
// `Client.send` with the intercepted event, so that the client can | ||
// override the sending mechanism. | ||
Raven._sendProcessedPayload = this.interceptRavenSend.bind(this); | ||
return Promise.resolve(true); | ||
return event; | ||
} | ||
/** The Sentry Browser SDK Backend. */ | ||
var BrowserBackend = /** @class */ (function () { | ||
/** Creates a new browser backend instance. */ | ||
function BrowserBackend(frontend) { | ||
/** In memory store for breadcrumbs. */ | ||
this.breadcrumbs = []; | ||
/** In memory store for context infos. */ | ||
this.context = {}; | ||
this.frontend = frontend; | ||
} | ||
/** | ||
* @inheritDoc | ||
*/ | ||
BrowserBackend.prototype.install = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _this = this; | ||
var dsn; | ||
return __generator(this, function (_a) { | ||
dsn = this.frontend.getDSN(); | ||
if (!dsn) { | ||
throw new core.SentryError('Invariant exception: install() must not be called when disabled'); | ||
} | ||
Raven.config(dsn.toString(), this.frontend.getOptions()).install(); | ||
// Hook into Raven's breadcrumb mechanism. This allows us to intercept | ||
// both breadcrumbs created internally by Raven and pass them to the | ||
// Frontend first, before actually capturing them. | ||
Raven.setBreadcrumbCallback(function (breadcrumb) { | ||
utils.forget(_this.frontend.addBreadcrumb(breadcrumb)); | ||
return false; | ||
}); | ||
// Hook into Raven's internal event sending mechanism. This allows us to | ||
// pass events to the frontend, before they will be sent back here for | ||
// actual submission. | ||
Raven._sendProcessedPayload = function (event) { | ||
utils.forget(_this.frontend.captureEvent(normalizeRavenEvent(event))); | ||
}; | ||
return [2 /*return*/, true]; | ||
}); | ||
}); | ||
}; | ||
SentryBrowser.prototype.getRaven = function () { | ||
return Raven; | ||
/** | ||
* @inheritDoc | ||
*/ | ||
BrowserBackend.prototype.eventFromException = function (exception) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var originalSend, event_1; | ||
return __generator(this, function (_a) { | ||
originalSend = Raven._sendProcessedPayload; | ||
try { | ||
Raven._sendProcessedPayload = function (evt) { | ||
event_1 = evt; | ||
}; | ||
Raven.captureException(exception); | ||
return [2 /*return*/, normalizeRavenEvent(event_1)]; | ||
} | ||
finally { | ||
Raven._sendProcessedPayload = originalSend; | ||
} | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
SentryBrowser.prototype.captureException = function (exception) { | ||
/** | ||
* @inheritDoc | ||
*/ | ||
BrowserBackend.prototype.eventFromMessage = function (message) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var originalSend, event_2; | ||
return __generator(this, function (_a) { | ||
// We are being called by the Client. We must not send the exception here, | ||
// which is why we capture and return it. The Client will then call `send`. | ||
return [2 /*return*/, this.capture(function () { return Raven.captureException(exception); })]; | ||
originalSend = Raven._sendProcessedPayload; | ||
try { | ||
Raven._sendProcessedPayload = function (evt) { | ||
event_2 = evt; | ||
}; | ||
Raven.captureMessage(message); | ||
return [2 /*return*/, normalizeRavenEvent(event_2)]; | ||
} | ||
finally { | ||
Raven._sendProcessedPayload = originalSend; | ||
} | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
SentryBrowser.prototype.captureMessage = function (message) { | ||
/** | ||
* @inheritDoc | ||
*/ | ||
BrowserBackend.prototype.storeContext = function (context) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
// We are being called by the Client. We must not send the message here, | ||
// which is why we capture and return it. The Client will then call `send`. | ||
return [2 /*return*/, this.capture(function () { return Raven.captureMessage(message); })]; | ||
this.context = __assign({}, context); | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
SentryBrowser.prototype.captureBreadcrumb = function (breadcrumb) { | ||
/** | ||
* @inheritDoc | ||
*/ | ||
BrowserBackend.prototype.loadContext = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
// We are being called by the Client. This means, the breadcrumb has been | ||
// processed already and we can pass it on to Raven. | ||
return [2 /*return*/, this.capture(function () { return Raven.captureBreadcrumb(breadcrumb); })]; | ||
return [2 /*return*/, this.context]; | ||
}); | ||
}); | ||
}; | ||
SentryBrowser.prototype.send = function (event) { | ||
return new Promise(function (resolve, reject) { | ||
sendRavenEvent(event, function (error) { | ||
if (error) { | ||
reject(error); | ||
} | ||
else { | ||
resolve(); | ||
} | ||
/** | ||
* @inheritDoc | ||
*/ | ||
BrowserBackend.prototype.sendEvent = function (event) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, new Promise(function (resolve) { | ||
sendRavenEvent(event, function (error) { | ||
// TODO: Check the response status code | ||
resolve(error ? 500 : 200); | ||
}); | ||
})]; | ||
}); | ||
}); | ||
}; | ||
SentryBrowser.prototype.wrap = function (fn, options) { | ||
return Raven.wrap(options, fn); | ||
/** | ||
* @inheritDoc | ||
*/ | ||
BrowserBackend.prototype.storeBreadcrumbs = function (breadcrumbs) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
this.breadcrumbs = __spread(breadcrumbs); | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
SentryBrowser.prototype.setOptions = function (options) { | ||
Object.assign(this.options, options); | ||
Object.assign(Raven._globalOptions, this.options); | ||
return Promise.resolve(); | ||
}; | ||
SentryBrowser.prototype.getContext = function () { | ||
/** | ||
* @inheritDoc | ||
*/ | ||
BrowserBackend.prototype.loadBreadcrumbs = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, Promise.resolve(Raven.getContext())]; | ||
return [2 /*return*/, __spread(this.breadcrumbs)]; | ||
}); | ||
}); | ||
}; | ||
SentryBrowser.prototype.setContext = function (context) { | ||
if (context.extra) { | ||
Raven.setExtraContext(context.extra); | ||
} | ||
if (context.user) { | ||
Raven.setUserContext(context.user); | ||
} | ||
if (context.tags) { | ||
Raven.setTagsContext(context.tags); | ||
} | ||
return Promise.resolve(); | ||
return BrowserBackend; | ||
}()); | ||
/** | ||
* The Sentry Browser SDK Frontend. | ||
* | ||
* @see BrowserOptions for documentation on configuration options. | ||
* @see SentryClient for usage documentation. | ||
*/ | ||
var BrowserFrontend = /** @class */ (function (_super) { | ||
__extends(BrowserFrontend, _super); | ||
/** | ||
* Creates a new Browser SDK instance. | ||
* @param options Configuration options for this SDK. | ||
*/ | ||
function BrowserFrontend(options) { | ||
return _super.call(this, BrowserBackend, options) || this; | ||
} | ||
/** | ||
* @inheritDoc | ||
*/ | ||
BrowserFrontend.prototype.getSdkInfo = function () { | ||
return { | ||
name: 'sentry-browser', | ||
version: Raven.VERSION, | ||
}; | ||
}; | ||
SentryBrowser.prototype.interceptRavenSend = function (event) { | ||
if (this.capturing) { | ||
// This event was requested via `SentryBrowser.captureException` or | ||
// `SentryBrowser.captureMessage`. We capture it, which will return it to | ||
// the `Client`. The client will call its `send` method automatically. | ||
this.captured = event; | ||
} | ||
else { | ||
// This event was generated inside RavenJS in a wrapped function or | ||
// global exception hook. We have to manually pass it to `Client.send`. | ||
// The client will then run all callbacks and decide how to send this | ||
// event. | ||
this.client.send(event); | ||
} | ||
/** | ||
* Instruments the given function and sends an event to Sentry every time the | ||
* function throws an exception. | ||
* | ||
* @param fn A function to wrap. | ||
* @returns The wrapped function. | ||
*/ | ||
// tslint:disable-next-line:ban-types | ||
BrowserFrontend.prototype.wrap = function (fn, options) { | ||
return Raven.wrap(options, fn); | ||
}; | ||
SentryBrowser.prototype.interceptRavenBreadcrumb = function (crumb) { | ||
if (this.capturing) { | ||
// This breadcrumb is being captured explicitly by the Client. We return | ||
// it so that Raven uses its internal mechanism to store it. | ||
this.captured = crumb; | ||
return crumb; | ||
} | ||
// The breadcrumb has been generated internally by Raven. We return `false` | ||
// to prevent Raven's default mechanism and pass it to the client instead. | ||
// The client can then run all callbacks and decide how to store the | ||
// breadcrumb. If SentryBrowser is in charge, the Client will call | ||
// `SentryBrowser.captureBreadcrumb` next, which will capture it (see | ||
// above). | ||
this.client.captureBreadcrumb(crumb); | ||
return false; | ||
}; | ||
SentryBrowser.prototype.capture = function (callback) { | ||
this.captured = undefined; | ||
this.capturing = true; | ||
callback(); | ||
var captured = this.captured; | ||
this.captured = undefined; | ||
this.capturing = false; | ||
if (captured === undefined) { | ||
throw new Error('Could not capture.'); | ||
} | ||
return captured; | ||
}; | ||
return SentryBrowser; | ||
}()); | ||
return BrowserFrontend; | ||
}(core.FrontendBase)); | ||
/** | ||
* The Sentry Browser SDK Client. | ||
* | ||
* To use this SDK, call the {@link Sdk.create} function as early as possible | ||
* when loading the web page. To set context information or send manual events, | ||
* use the provided methods. | ||
* | ||
* @example | ||
* const { SentryClient } = require('@sentry/browser'); | ||
* | ||
* SentryClient.create({ | ||
* dsn: '__DSN__', | ||
* // ... | ||
* }); | ||
* | ||
* @example | ||
* SentryClient.setContext({ | ||
* extra: { battery: 0.7 }, | ||
* tags: { user_mode: 'admin' }, | ||
* user: { id: '4711' }, | ||
* }); | ||
* | ||
* @example | ||
* SentryClient.addBreadcrumb({ | ||
* message: 'My Breadcrumb', | ||
* // ... | ||
* }); | ||
* | ||
* @example | ||
* SentryClient.captureMessage('Hello, world!'); | ||
* SentryClient.captureException(new Error('Good bye')); | ||
* SentryClient.captureEvent({ | ||
* message: 'Manual', | ||
* stacktrace: [ | ||
* // ... | ||
* ], | ||
* }); | ||
* | ||
* @see BrowserOptions for documentation on configuration options. | ||
*/ | ||
// tslint:disable-next-line:variable-name | ||
var SentryClient = new core.Sdk(BrowserFrontend); | ||
exports.SentryBrowser = SentryBrowser; | ||
exports.BrowserBackend = BrowserBackend; | ||
exports.BrowserFrontend = BrowserFrontend; | ||
exports.SentryClient = SentryClient; |
{ | ||
"name": "@sentry/browser", | ||
"version": "0.4.0-beta.4", | ||
"version": "0.4.0-beta.5", | ||
"description": "Offical Sentry SDK for browsers", | ||
"repository": "https://github.com/getsentry/raven-js", | ||
"author": "Sentry", | ||
@@ -16,16 +17,17 @@ "license": "MIT", | ||
"dependencies": { | ||
"@sentry/core": "^0.4.0-beta.4", | ||
"raven-js": "^3.22.1" | ||
"@sentry/core": "^0.4.0-beta.5", | ||
"@sentry/utils": "^0.4.0-beta.5", | ||
"raven-js": "^3.23.1" | ||
}, | ||
"devDependencies": { | ||
"karma": "*", | ||
"prettier": "*", | ||
"rimraf": "*", | ||
"rollup": "*", | ||
"rollup-plugin-commonjs": "*", | ||
"rollup-plugin-node-resolve": "*", | ||
"rollup-plugin-typescript2": "*", | ||
"rollup-plugin-uglify": "*", | ||
"tslint": "*", | ||
"typescript": "*" | ||
"chai": "^4.1.2", | ||
"karma": "^2.0.0", | ||
"npm-run-all": "^4.1.2", | ||
"prettier": "^1.11.1", | ||
"prettier-check": "^2.0.0", | ||
"rimraf": "^2.6.2", | ||
"rollup": "^0.56.4", | ||
"sinon": "^4.4.3", | ||
"tslint": "^5.9.1", | ||
"typescript": "^2.7.2" | ||
}, | ||
@@ -35,4 +37,8 @@ "scripts": { | ||
"clean": "rimraf dist coverage .rpt2_cache build", | ||
"lint": "tslint --config ../../tslint.json src/**/*", | ||
"format": "prettier --config ../../.prettierrc.json src/**/* --write", | ||
"lint": "run-s lint:prettier lint:tslint", | ||
"lint:prettier": "prettier-check '{src,test}/**/*.ts'", | ||
"lint:tslint": "tslint -t stylish -p .", | ||
"fix": "run-s fix:tslint fix:prettier", | ||
"fix:prettier": "prettier --write '{src,test}/**/*.ts'", | ||
"fix:tslint": "tslint --fix -t stylish -p .", | ||
"test": "karma start karma.config.js", | ||
@@ -39,0 +45,0 @@ "test:watch": "karma start karma.config.js --auto-watch --no-single-run", |
106
README.md
<p align="center"> | ||
<a href="https://sentry.io" target="_blank" align="center"> | ||
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280"> | ||
</a> | ||
<br/> | ||
<h1>Sentry Browser SDK Package</h1> | ||
<a href="https://sentry.io" target="_blank" align="center"> | ||
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280"> | ||
</a> | ||
<br /> | ||
</p> | ||
# Official Sentry SDK for Browsers (JavaScript) | ||
[![npm version](https://img.shields.io/npm/v/@sentry/browser.svg)](https://www.npmjs.com/package/@sentry/browser) | ||
@@ -13,50 +14,83 @@ [![npm dm](https://img.shields.io/npm/dm/@sentry/browser.svg)](https://www.npmjs.com/package/@sentry/browser) | ||
## General | ||
This package is meant to be used with the Core SDK package. | ||
## Usage | ||
First you have to create the core and `use` a corresponding SDK. | ||
To use this SDK, call `SentryClient.create(options)` as early as possible after | ||
loading the page. This will initialize the SDK and hook into the environment. | ||
Note that you can turn off almost all side effects using the respective options. | ||
```javascript | ||
import * as Sentry from '@sentry/core'; | ||
import { SentryBrowser } from '@sentry/Sentrybrowser'; | ||
import { SentryClient } from '@sentry/browser'; | ||
Sentry.create('__DSN__') | ||
.use(SentryBrowser) | ||
.install(); | ||
SentryClient.create({ | ||
dsn: '__DSN__', | ||
// ... | ||
}); | ||
``` | ||
After that you can call function on the global `sharedClient`: | ||
To set context information or send manual events, use the provided methods on | ||
`SentryClient`. Note that these functions will not perform any action before you | ||
have called `SentryClient.install()`: | ||
```javascript | ||
Sentry.getSharedClient().setTagsContext({ cordova: true }); | ||
Sentry.getSharedClient().captureMessage('test message'); | ||
Sentry.getSharedClient().captureBreadcrumb({ message: 'HOHOHOHO' }); | ||
Sentry.getSharedClient().captureException(new Error('error')); | ||
// Set user information, as well as tags and further extras | ||
SentryClient.setContext({ | ||
extra: { battery: 0.7 }, | ||
tags: { user_mode: 'admin' }, | ||
user: { id: '4711' }, | ||
}); | ||
// Add a breadcrumb for future events | ||
SentryClient.addBreadcrumb({ | ||
message: 'My Breadcrumb', | ||
// ... | ||
}); | ||
// Capture exceptions, messages or manual events | ||
SentryClient.captureMessage('Hello, world!'); | ||
SentryClient.captureException(new Error('Good bye')); | ||
SentryClient.captureEvent({ | ||
message: 'Manual', | ||
stacktrace: [ | ||
// ... | ||
], | ||
}); | ||
``` | ||
## Advanced Usage | ||
If you don't want to use a global static instance of Sentry, you can create one | ||
on your own: | ||
yourself: | ||
```javascript | ||
const client = await new Sentry.Client(dsn).use(MockAdapter).install() | ||
client.setTagsContext({ cordova: true }); | ||
client.captureMessage('test message'); | ||
client.captureBreadcrumb({ message: 'HOHOHOHO' }); | ||
import { BrowserFrontend } from '@sentry/browser'; | ||
// OR | ||
const client = new BrowserFrontend({ | ||
dsn: '__DSN__', | ||
// ... | ||
}); | ||
new Sentry.Client('__DSN__') | ||
.use(MockAdapter) | ||
.install() | ||
.then(client => { | ||
client.setTagsContext({ cordova: true }); | ||
client.captureMessage('test message'); | ||
client.captureBreadcrumb({ message: 'HOHOHOHO' }); | ||
}); | ||
client.install(); | ||
// ... | ||
``` | ||
Notice, `install()` is a `Promise` but we internally wait until it is resolved, | ||
so it is save to call other function without waiting for it. | ||
Note that `install()` returns a `Promise` that resolves when the installation | ||
has finished. It is not necessary to wait for the installation before adding | ||
breadcrumbs, defining context or sending events. However, the return value | ||
indicates whether the installation was successful and the environment could be | ||
instrumented: | ||
```javascript | ||
import { BrowserFrontend } from '@sentry/browser'; | ||
const client = new BrowserFrontend({ | ||
dsn: '__DSN__', | ||
// ... | ||
}); | ||
const success = await client.install(); | ||
if (success) { | ||
// Will catch global exceptions, record breadcrumbs for DOM events, etc... | ||
} else { | ||
// Limited instrumentation, but sending events will still work | ||
} | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
22276
9
503
96
3
1
+ Added@sentry/utils@^0.4.0-beta.5
+ Added@sentry/utils@0.4.2(transitive)
Updated@sentry/core@^0.4.0-beta.5
Updatedraven-js@^3.23.1