Some checks failed
Build & Deploy KLZ Cables / 🔍 Prepare Environment (push) Successful in 7s
Build & Deploy KLZ Cables / 🏗️ Build App (push) Successful in 4m3s
Build & Deploy KLZ Cables / 🏗️ Build Gatekeeper (push) Successful in 20s
Build & Deploy KLZ Cables / 🚀 Deploy (push) Has been cancelled
Build & Deploy KLZ Cables / ⚡ PageSpeed (push) Has been cancelled
Build & Deploy KLZ Cables / 🔔 Notifications (push) Has been cancelled
Build & Deploy KLZ Cables / 🧪 Quality Assurance (push) Has been cancelled
72 lines
2.4 KiB
TypeScript
72 lines
2.4 KiB
TypeScript
import * as Sentry from '@sentry/nextjs';
|
|
import type {
|
|
ErrorReportingLevel,
|
|
ErrorReportingService,
|
|
ErrorReportingUser,
|
|
} from './error-reporting-service';
|
|
import type { NotificationService } from '../notifications/notification-service';
|
|
|
|
type SentryLike = typeof Sentry;
|
|
|
|
export type GlitchtipErrorReportingServiceOptions = {
|
|
enabled: boolean;
|
|
};
|
|
|
|
// GlitchTip speaks the Sentry protocol; @sentry/nextjs can send to GlitchTip via DSN.
|
|
export class GlitchtipErrorReportingService implements ErrorReportingService {
|
|
constructor(
|
|
private readonly options: GlitchtipErrorReportingServiceOptions,
|
|
private readonly notifications?: NotificationService,
|
|
private readonly sentry: SentryLike = Sentry,
|
|
) {}
|
|
|
|
async captureException(error: unknown, context?: Record<string, unknown>) {
|
|
if (!this.options.enabled) return undefined;
|
|
const result = this.sentry.captureException(error, context as any) as any;
|
|
|
|
// Send to Gotify if it's considered critical or if we just want all exceptions there
|
|
// For now, let's send all exceptions to Gotify as requested "notify me via gotify about critical error messages"
|
|
// We'll treat all captureException calls as potentially critical or at least noteworthy
|
|
if (this.notifications) {
|
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
const contextStr = context ? `\nContext: ${JSON.stringify(context, null, 2)}` : '';
|
|
|
|
await this.notifications.notify({
|
|
title: '🔥 Critical Error Captured',
|
|
message: `Error: ${errorMessage}${contextStr}`,
|
|
priority: 7,
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
captureMessage(message: string, level: ErrorReportingLevel = 'error') {
|
|
if (!this.options.enabled) return undefined;
|
|
return this.sentry.captureMessage(message, level as any) as any;
|
|
}
|
|
|
|
setUser(user: ErrorReportingUser | null) {
|
|
if (!this.options.enabled) return;
|
|
this.sentry.setUser(user as any);
|
|
}
|
|
|
|
setTag(key: string, value: string) {
|
|
if (!this.options.enabled) return;
|
|
this.sentry.setTag(key, value);
|
|
}
|
|
|
|
withScope<T>(fn: () => T, context?: Record<string, unknown>) {
|
|
if (!this.options.enabled) return fn();
|
|
|
|
return this.sentry.withScope((scope) => {
|
|
if (context) {
|
|
for (const [key, value] of Object.entries(context)) {
|
|
scope.setExtra(key, value);
|
|
}
|
|
}
|
|
return fn();
|
|
});
|
|
}
|
|
}
|