getsentry / sentry-javascript

Official Sentry SDKs for JavaScript
https://sentry.io
MIT License
7.87k stars 1.55k forks source link

Vue integration does not work when using Sentry Client directly #3381

Closed eslawski closed 1 year ago

eslawski commented 3 years ago

Package + Version

Version:

@sentry/browser: 6.2.5
@sentry/integrations: 6.2.5

Description

We are using the Sentry BrowserClient as follows:

import Vue from "vue";
import * as Sentry from "@sentry/browser";
import { Vue as VueIntegration } from "@sentry/integrations";

const sentryClient = new Sentry.BrowserClient({
    dsn: "blah",
    integrations: [
        ...Sentry.defaultIntegrations,
        new VueIntegration({
            Vue,
            attachProps: true,
            logErrors: true
        })
    ],
});
const sentryHub = new Sentry.Hub(sentryClient);

// For non-Vue errors we can capture manually by doing this
this.sentryHub.run((sentryHub) => sentryHub.captureException(error))

// However we don't get the automatic error handling/reporting VueIntegration should be providing

We understand that the VueIntegration is designed to hook into the Vue.config.errorHandler and automatically report errors out as they arise. We did some debugging, and can confirm that the errorHandler is properly attaching itself.

However when an error is handled by this function, it never actually gets sent out to the Sentry. The root cause appears to be an issue with the getCurrentHub() not containing the Vue integration (this check fails).

Using BrowserClient directly like this (as opposed to Sentry.init) is important to our microfrontend architecture where teams own smaller parts of a single page (sometimes even using different technologies: Vue, React, etc.). Having a way to report out errors to different dsns is a requirement for us. And we would love to be able to use the Vue Integration (and other technologies) too!

onurtemizkan commented 3 years ago

Related: #1969

@eslawski, after creating the hub, it needs to be registered as the currentHub for automatic error handling to work. The manual capturing will still work because each run call creates a temporary hub.

Could you try:

import Vue from "vue";
import * as Sentry from "@sentry/browser";
import { Vue as VueIntegration } from "@sentry/integrations";
import { makeMain } from "@sentry/hub";

const sentryClient = new Sentry.BrowserClient({
    dsn: "blah",
    integrations: [
        ...Sentry.defaultIntegrations,
        new VueIntegration({
            Vue,
            attachProps: true,
            logErrors: true
        })
    ],
});
const sentryHub = new Sentry.Hub(sentryClient);
makeMain(sentryHub);

// ...

And please let me know if that resolves the issue.

eslawski commented 3 years ago

Hey @onurtemizkan thanks for the response.

So calling makeMain(sentryHub) as you have above does in fact get the Vue integration working! However, I have noticed some other unintended side effects.

Specifically I am seeing that this Hub is now automatically handling ALL errors that occur on the page. I believe I tracked this down to the behavior of the GlobalHandlers integration, which comes included with the Sentry.defaultIntegrations. We don't really want this. Our entire purpose of using a BrowserClient and Hub directly (instead of Sentry.init) is to be able to have multiple Sentry instances monitoring the page at one time. This need comes from the fact that our pages are composed of many different javascript apps (sometimes even in different technologies). Having separated error monitoring solutions per/app instead of per/page is an important part of the setup.

That said, I was able to work around this by not supplying the Sentry.defaultIntegrations, which should work for the time being.

During this process, I also noticed that the Breadcrumbs integration is not working (even after calling makeMain). After poking around some other issues I came across https://github.com/getsentry/sentry-javascript/issues/3271 and https://github.com/getsentry/sentry-javascript/issues/2732 which sounds like a known limitation at the moment with v6? I know this topic is a bit of tangent from the original issue, but it sounds like in v7 we can expect better support for monitoring pages on a more granular level?

smeubank commented 1 year ago

https://docs.sentry.io/platforms/javascript/guides/vue/

So there is a Vue SDK now

And we also have this discussion with an example repo with tips for dealing with situation requiring multiple sentry instances.

https://github.com/getsentry/sentry-javascript/discussions/5217

I would propose to close this issue, since the original problem is solved and we have a number of discussions around microfrontends and multiple sentry instance. Hope that is OK

eslawski commented 1 year ago

Thanks for the response @smeubank . If I am following your suggestion correctly, the Vue integration you recommend leverages Sentry.init as a means of registering multiple Vue applications that live in the same project. Due to our microfrontend architecture we are unable to use Sentry.init as it sets up page level error monitoring that we don't want (we want error monitoring to be distributed - hence the direct use of the BrowserClient). Additionally each microfrontend lives in its own project.

So maybe this is more of a limitation for microfrontends at the moment? FWIW I have already filled out the request for feedback post you linked. Thanks!