New JavaScript SDKs - Feedback wanted


#1

< back to posts

Javascript Forum

As already announced in the Blog Post we were working on rewriting our SDKs to streamline the experience across different environments.
You can find an overview of the SDKs in the readme here: https://github.com/getsentry/raven-js

You can identify them by the @sentry/* namespace on NPM. The goal in this new lineup is to provide a more convenient interface and improved consistency between various JavaScript environments.

Updated Interface

import { init, captureMessage } from '@sentry/browser';

init({
  dsn: '__DSN__',
  // ...
});

captureMessage('Hello, world!');

Library minimal
A new feature of this SDK lineup is the minimal package. It allows library authors add support for a Sentry SDK without having to bundle the entire SDK or being dependent on a specific platform. If the library is included and a Sentry SDK is present, it will automagically work:

import * as Sentry from '@sentry/minimal';

// Add a breadcrumb for future events
Sentry.addBreadcrumb({
  message: 'My Breadcrumb',
  // ...
});

// Capture exceptions, messages or manual events
Sentry.captureMessage('Hello, world!');
Sentry.captureException(new Error('Good bye'));
Sentry.captureEvent({
  message: 'Manual',
  stacktrace: [
    // ...
  ],
});

We hope to see library authors adopt this feature in the future to facilitate better error tracking across the ecosystem.

Scope concept
We introduced a new concept we called Scope. A Scope holds an isolated state of breadcrumbs, context and other metadata. raven-node and raven-js had a similar feature, ambiguously called “context”. There always is a “default” Scope which handles all the stuff as we did before you have to do nothing but we also support pushing new a Scope if you ever want to have isolated context information lets say for example, each request that comes in in a node application should have it’s own Scope.
To add extra, tags or user to your event you have to call:

import * as Sentry from '@sentry/browser';

// Set user information, as well as tags and further extras
Sentry.configureScope(scope => {
  scope.setExtra('battery', 0.7);
  scope.setTag('user_mode', 'admin');
  scope.setUser({ id: '4711' });
  // scope.clear();
});

Sentry.captureMessage("Hello World!"); // This event contains all scope information from the global scope

If you want to have isolated information for only on specific event you can to:

import * as Sentry from '@sentry/browser';

Sentry.getDefaultHub().withScope(() => {
   // We are here in an isolated new Scope, we inherited all the stuff from the parent 
   // but after this functions returns the Scope is popped and removed

  Sentry.configureScope(scope => {
    scope.setExtra('battery', 0.9); // We overwrite battery extra
  });

  Sentry.captureMessage("Hello World!"); // This will contain all scope info from before + battery is overwritten just for this message
});

ref: https://github.com/getsentry/raven-js/issues/1281


#2

@HazAT Where I work, I maintain a library that composes raven-node in order to extract common information from the environment which includes parsing the user from an express request if/when an error occurs, promoting some headers to tags for filtering, and ignoring some errors based on what environment you’re in.

Previously, I was accomplishing all of this pretty easily with a combination of parseUser, dataCallback, and beforeSendCallback.

It looks like I could accomplish most/all of this using the beforeSend callback in the new SDKs, but it feels like the correct approach would be to use an integration.

There’s very little documentation about creating custom integrations, but based on the ones in the @sentry/node package, it seems like using addGlobalEventProcessor from the current hub is the way to go, but it’s not exported from @sentry/node. Is that a bug/oversight, or is there a different way to accomplish what I’m trying to do that’s already publicly exposed?


#3

Thanks for your feedback on this matter, you are right, writing your own Integration would be the cleanest way to handle this.
I agree that our docs about writing your own integration can be improved by a lot (not many people asked for this yet).

That we did not expose addGlobalEventProcessor is a mistake on our part, we recently introduced this with 4.2.0, we will fix that in the next update.
(Release should come this week)


#4

4.2.4 has been released exposing addGlobalEventProcessor


#5

// Capture exceptions, messages or manual events
Sentry.captureMessage(‘Hello, world!’);
Sentry.captureException(new Error(‘Good bye’));
Sentry.captureEvent({
message: ‘Manual’,
stacktrace: [
// …
],
});

For me the biggest frustration is I can’t find the API documentation which explains these. Can I pass an Object to capture message, or does it only accept a string?

For captureEvent can it be any object, or must I have an Object with message and stacktrace?