mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: replace require() with dynamic import() for analytics modules
PostHog and Sentry were silently disabled in production Docker builds.
The app runs as ESM ("type": "module") via tsx, where require() is not
defined. The catch blocks swallowed the ReferenceError, leaving both
clients as null. Switch to await import() and store the Sentry module
reference for use in the error handler.
This commit is contained in:
@@ -8,7 +8,7 @@ import Fastify from "fastify";
|
||||
import { env } from "./config.js";
|
||||
import { db, schema } from "./db/index.js";
|
||||
import { runMigrations } from "./db/migrate.js";
|
||||
import { initAnalytics, shutdownAnalytics } from "./lib/analytics.js";
|
||||
import { captureException, initAnalytics, shutdownAnalytics } from "./lib/analytics.js";
|
||||
import { startCleanupCron } from "./lib/cleanup.js";
|
||||
import { ensureAiDirs, recoverInterruptedInstalls } from "./lib/feature-status.js";
|
||||
import { shutdownWorkerPool } from "./lib/worker-pool.js";
|
||||
@@ -53,7 +53,7 @@ function ensureInstanceId() {
|
||||
}
|
||||
|
||||
ensureInstanceId();
|
||||
initAnalytics();
|
||||
await initAnalytics();
|
||||
|
||||
// Mark any jobs left in processing/queued from a previous unclean shutdown
|
||||
recoverStaleJobs();
|
||||
@@ -75,12 +75,7 @@ app.setErrorHandler((error: Error & { statusCode?: number }, request, reply) =>
|
||||
{ err: error, url: request.url, method: request.method },
|
||||
"Unhandled request error",
|
||||
);
|
||||
try {
|
||||
const Sentry = require("@sentry/node") as typeof import("@sentry/node");
|
||||
Sentry.captureException(error);
|
||||
} catch {
|
||||
// Sentry not available
|
||||
}
|
||||
captureException(error);
|
||||
const isProduction = process.env.NODE_ENV === "production";
|
||||
reply.status(statusCode).send({
|
||||
error: statusCode >= 500 ? "Internal server error" : error.message,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import type { FastifyRequest } from "fastify";
|
||||
import type { PostHog } from "posthog-node";
|
||||
import { env } from "../config.js";
|
||||
import { db, schema } from "../db/index.js";
|
||||
import { getAuthUser } from "../plugins/auth.js";
|
||||
@@ -8,13 +9,14 @@ const FILE_EXT_PATTERN =
|
||||
/\.(jpe?g|png|pdf|webp|gif|tiff?|bmp|svg|he[ic]f?|avif|raw|cr2|nef|arw|dng|psd|tga|exr|hdr)\b/gi;
|
||||
const FILE_PATH_PATTERN = /\/(tmp\/workspace|data\/files|data\/ai)\//g;
|
||||
|
||||
let posthogClient: import("posthog-node").PostHog | null = null;
|
||||
let posthogClient: PostHog | null = null;
|
||||
let sentryModule: typeof import("@sentry/node") | null = null;
|
||||
|
||||
export function initAnalytics(): void {
|
||||
export async function initAnalytics(): Promise<void> {
|
||||
if (!env.ANALYTICS_ENABLED || !env.POSTHOG_API_KEY) return;
|
||||
|
||||
try {
|
||||
const { PostHog } = require("posthog-node") as typeof import("posthog-node");
|
||||
const { PostHog } = await import("posthog-node");
|
||||
posthogClient = new PostHog(env.POSTHOG_API_KEY, {
|
||||
host: env.POSTHOG_HOST,
|
||||
flushAt: 20,
|
||||
@@ -26,8 +28,8 @@ export function initAnalytics(): void {
|
||||
|
||||
if (env.SENTRY_DSN) {
|
||||
try {
|
||||
const Sentry = require("@sentry/node") as typeof import("@sentry/node");
|
||||
Sentry.init({
|
||||
sentryModule = await import("@sentry/node");
|
||||
sentryModule.init({
|
||||
dsn: env.SENTRY_DSN,
|
||||
sendDefaultPii: false,
|
||||
beforeSend(event) {
|
||||
@@ -70,17 +72,19 @@ export function initAnalytics(): void {
|
||||
}
|
||||
}
|
||||
|
||||
export function captureException(error: unknown): void {
|
||||
sentryModule?.captureException(error);
|
||||
}
|
||||
|
||||
export async function shutdownAnalytics(): Promise<void> {
|
||||
if (posthogClient) {
|
||||
await posthogClient.shutdown();
|
||||
posthogClient = null;
|
||||
}
|
||||
|
||||
try {
|
||||
const Sentry = require("@sentry/node") as typeof import("@sentry/node");
|
||||
await Sentry.close(2000);
|
||||
} catch {
|
||||
// @sentry/node not available
|
||||
if (sentryModule) {
|
||||
await sentryModule.close(2000);
|
||||
sentryModule = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user