npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@personio/alerting

v0.2.5

Published

A package to report frontend errors on sentry

Downloads

2,669

Readme

Alerting

An npm package for micro-frontends to report frontend errors to Sentry

About

This packages leverages the BrowserClient and Hub APIs to create a Sentry instance dedicated to the micro-frontend it is running on.

Unlike the Sentry.init API, this ensures that in a webpage with multiple micro-frontends, we can have multiple instances of Sentry each dedicated to one micro-frontend. Behind the scenes, this package will ensure that only the errors occurring from the micro-frontend bundle the Sentry instance is running on get reported to the Sentry project this Sentry instance is tied to.

For example, a webpage with two micro-frontends MFE-A and MFE-B each having their own Sentry instance Sentry-A and Sentry-B where MFE-A throws an error on a click event, the internal working of these Sentry instances will ensure that Sentry-A reports this event on the MFE-A Sentry project while Sentry-B will simply ignore this error.

Installation

Install the package:

yarn add @personio/alerting

:warning: Note! :warning:

@personio/alerting already comes with both @sentry/browser and @sentry/cli bundled as dependencies. There is no need to have them in your project, so feel free to remove them if you do.

yarn remove @sentry/browser @sentry/cli

Minimal Usage

First, you need to add the crossorigin attribute to your bundle's script tag and set its value to anonymous. This is what allows us to detect which JS file an error originated from.

For mFEs not in use on production:

<script src="<cdn>/my-mfe/8BADF00D.js" crossorigin="anonymous" defer></script>

For mFEs in use on production for at least one customer:

Note that we are adding a queryParam to the src of the script tag called crossOriginCacheBuster. We need to do this to make sure that when this code goes on production, the cached JS file for the mFE is invalidated by the browser and instead it is fetched from the CDN. This will ensure that the response from CDN has the ACAO headers set correctly

<script
  src="<cdn>/my-mfe/8BADF00D.js?crossOriginCacheBuster"
  crossorigin="anonymous"
  defer
></script>

Next, the minimal implementation is to wrap your application with the package's SentryProvider component, and pass the necessary Sentry config options via props.

import { SentryProvider } from '@personio/alerting';

…

<SentryProvider
  dsn={SENTRY_DSN}
  env={ENV}
  name={MICRO_FRONTEND_NAME}
  version={MICRO_FRONTEND_VERSION}
  enabled={IS_SENTRY_ENABLED}
>
  <App />
</Sentryprovider>

Potential issues

  • if the webpack dev server is not setup properly, while consuming local instance of mFE from local Monolith the following error may appear:

    Access to script at ... from origin ... has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

    In order to resolve it, make sure that webpack dev server is configured in way so it works properly with CORS headers, which means that build-utils/webpack.development.js (or similar) file in the mFE must have devServer.headers conf section which includes 'Access-Control-Allow-Origin': '*.dev.personio.de',.

In what order should I deploy the changes in the monolith and my mFE

You should first merge the MR on the monolith with the newly added crossorigin attribute

Once the monolioth deployment has finished, you can go ahead and deploy your mFE

Integration with Error Boundary

The package also provides aSentryErrorBoundary component which you can use in your MFE to automatically catch and report rendering errors to your Sentry instance.

import { SentryErrorBoundary } from '@personio/alerting';

…

<SentryErrorBoundary errorComponent={<div>Something went wrong</div>}>
  <TemperamentalComponent />
</SentryErrorBoundary>

If you wish to only use this as an ErrorBoundary and not have it report to Sentry, you can pass false to the reportRenderError prop.

import { SentryErrorBoundary } from '@personio/alerting';

…

<SentryErrorBoundary
  errorComponent={<div>Something went wrong</div>}
  reportRenderError={false}
>
  <TemperamentalComponent />
</SentryErrorBoundary>

Manually Capturing Exceptions

@personio/alerting also exposes the internal method used to capture exceptions through the Context, allowing you to manually capture your own exceptions where needed. You can optionally pass extras which will appear alongside your alert in Sentry, with default environment, mfe_name, and mfe_version values.

Note: this is preferred to using the Sentry Hub instance directly.

import { nanoid } from 'nanoid';
import { useSentry } from '@personio/alerting';

const PokemonDetails = () => {
  const { capture } = useSentry();

  const fetchPokemon = (id) => {
    let data = {};
    try {
      const res = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
      data = await res.json();
    } catch (err) {
      // `capture` checks if Sentry is enabled internally
      capture(err, { uuid: nanoid() });
    }
    return data;
  };
};

Accessing the Sentry Hub

We leverage React Context under-the-hood to store an instance of Sentry Hub and handle the reporting. This Hub and Context are available as an escape hatch, a means of directly reporting from custom locations, or to further enrich events with additional info.

The Hub (and your Sentry instance's enabled status) is exposed through a custom hook that can be consumed anywhere in your app that hooks can normally be used.

Note: this is entirely optional and, typically, you will never use it.

import { nanoid } from 'nanoid';
import { useSentry } from '@personio/alerting';

const PokemonDetails = () => {
  const { enabled, hub } = useSentry();

  const fetchPokemon = (id) => {
    let data = {};
    try {
      const res = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
      data = await res.json();
    } catch (err) {
      if (enabled) {
        hub.setTag('uuid', nanoid());
        hub.captureException(err);
      }
    }
    return data;
  };
};