Skip to content

Instantly share code, notes, and snippets.

@cas-technology
Created June 15, 2023 13:22
Show Gist options
  • Save cas-technology/61eab999b3f58e689409b62adf12007c to your computer and use it in GitHub Desktop.
Save cas-technology/61eab999b3f58e689409b62adf12007c to your computer and use it in GitHub Desktop.
Sentry plugin for Nuxt 3
import * as Sentry from '@sentry/vue';
import { Integrations } from '@sentry/tracing';
import { Event, EventHint, User } from '@sentry/types';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const SentryPlugin: any = defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig().public;
const { vueApp } = nuxtApp;
// set the config (env) variables and provide some defaults
const dsn = config.SENTRY_DSN;
// Sentry recommends adjusting this value in production, lower = less stress on Sentry and the user system
const tracesSampleRate: number = +config.SENTRY_TRACES_SAMPLE_RATE || 0.1;
const debug = config.SENTRY_ENABLE_DEBUG.toLowerCase() === 'true';
const environment: string = config.ENVIRONMENT || 'PRODUCTION';
// only trace the allowed domains, this prevents browser plugin errors from showing up on Sentry
const tracingOrigins: string[] = config.SENTRY_ORIGINS?.split(',') || [
'example.dev',
];
const router = useRouter();
Sentry.init({
app: [vueApp],
dsn,
// disables the native Vue/Nuxt console.error logging as this creates an infinite loop!
logErrors: false,
integrations: [
// provide the $router to Sentry, so it knows where in the application the user is
new Integrations.BrowserTracing({
routingInstrumentation: Sentry.vueRouterInstrumentation(router),
tracingOrigins,
}),
],
tracesSampleRate,
debug,
environment,
// As we disabled the native logger, we need to determine what to do with the errors
beforeSend(event: Event, hint: EventHint) {
// Only exceptions are 'errors' so we console.error those
if (event.exception) {
if (debug) {
// eslint-disable-next-line no-console
console.error(
`[Exeption handled]: (${hint.originalException})`,
event,
hint,
);
} else {
// eslint-disable-next-line no-console
console.error(
`[Exeption handled]: (${hint.originalException})`,
);
}
}
return event;
},
});
// Create the mixin, see https://docs.sentry.io/platforms/javascript/guides/vue/
vueApp.mixin(
Sentry.createTracingMixins({
trackComponents: true,
timeout: 2000,
hooks: ['activate', 'mount', 'update'],
}),
);
// Configure the default error handler. No configuration added as these should always be set
Sentry.attachErrorHandler(vueApp, {
logErrors: false,
attachProps: true,
trackComponents: true,
timeout: 2000,
hooks: ['activate', 'mount', 'update'],
});
const developer: string =
config.DEVELOPER.length > 0 ? config.DEVELOPER : '';
// if the DEVELOPER is set, link the username, so we can easily see who needs to see the error on the DEV env
if (developer.length > 0) {
Sentry.setUser({
username: developer,
});
}
return {
/**
* provide documentation: https://vuejs.org/guide/components/provide-inject.html
*
* Used to provide setter functions for common Sentry debugging variables from _within_ components
*
* Usage example:
* const { $sentrySetContext, $sentrySetUser } = useNuxtApp();
* $sentrySetUser({ email: 'some@email.com' });
*/
provide: {
// in some use-cases we need to provide a new context
sentrySetContext: (
name: string,
context: {
[key: string]: never;
} | null,
) => Sentry.setContext(name, context),
// provide a setter for the User. See the User type for the supported objects
sentrySetUser: (user: User) => Sentry.setUser(user),
},
};
});
export default SentryPlugin;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment