Effective Strategies for Error Handling in Embeddable Widgets
Tags: errors, monitoring, sentry
Published: 2023-09-18 11:32:09

At Woovi, we think carefully about how to make life easier for developers who consume our APIs.
The most common case is to create a new Pix payment request and render the QR Code inside the e-commerce/website of our user. 
Instead of making our users rebuild every time the same frontend to render the QR Code and payment information, we provide a Woovi Widget that lets them render the same UI of our payment link embedded in their website.

Below is an example of the Widget. It is not only layout and design, it has a timer, logic, and real-time updates using web sockets.
Rebuilding this from scratch is a lot of work.


![Woovi Widget](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1yadbhitb9twxzqrslff.png)

To get the same interface as above, the user just needs to add one div and one script tag, and it is done.

```html
<body>
    <!-- OpenPix order -->
    <div 
      id='woovi-order' 
      data-appid={"your app id"}
      data-correlationid={"charge correlationID"} 
    />
    <script src="https://plugin.woovi.com/v1/woovi.js" async></script>
  </body>
```

## Error Monitoring
Our e-commerce plugins use this widget, so we make sure we provide always the same user experience across each e-commerce platform.
We have thousands of users depending on this widget every day.
To ensure we won't break or catch errors in a proactive way, we set up Sentry to catch all errors.

The problem is that Sentry was catching all errors, not only our widget errors but also all e-commerce unrelated errors.
This was causing a lot of errors to be sent to our Sentry, consuming all our quota. 100k of errors.

The basic Sentry setup is like this

```jsx
Sentry.init({
    dsn: config.SENTRY_DSN,
  });
```

The problem with this approach is that it will use `window.onerror` and catch all JavaScript errors that it is thrown, catching errors not related to our widget.

The solution was to use Sentry client directly with a custom ErrorBoundary.
An ErrorBoundary also ensure our widget won't break the e-commerce.

```jsx
const client = new BrowserClient({
  dsn: config.SENTRY_DSN,
  transport: makeFetchTransport,
  stackParser: defaultStackParser,
  integrations: defaultIntegrations,
});

const App = () => {
   return (
    <SentryErrorBoundary>
      <Widget />
    </SentryErrorBoundary>
   )
} 
```

## In Resume
As you grow, you need to revalidate if everything is working as expected.

The basic Sentry tutorial worked well for our 6 frontends, however, it was not suited for our embedded widget.

The Sentry building blocks were good enough to attend our new use case. This is a case where removing one level of abstraction was good enough. Sometimes, if the package or service is not well designed you need to switch to something else, or even worse, build from scratch.

---
Woovi
[Woovi](https://www.woovi.com) is a Startup that enables shoppers to pay as they like. To make this possible, Woovi provides instant payment solutions for merchants to accept orders.

If you want to work with us, we are [hiring](https://woovi.com/jobs/)!

---
Photo by <a href="https://unsplash.com/@marekokon?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Marek Okon</a> on <a href="https://unsplash.com/photos/ugm-yDj9Hi4?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>