From 972d2a97663c9ccac7ec8a7c9c9dd916dc8b6801 Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 20 Jul 2026 10:41:55 +0100 Subject: [PATCH] feat: enhance Sentry integration with dynamic loading and status reporting --- index.html | 2 +- js/main.js | 12 +++++++----- js/sentry.js | 31 ++++++++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/index.html b/index.html index 71d8718..a41edfd 100644 --- a/index.html +++ b/index.html @@ -423,6 +423,7 @@
+
- diff --git a/js/main.js b/js/main.js index 6f25a9e..aa199ea 100644 --- a/js/main.js +++ b/js/main.js @@ -453,19 +453,20 @@ async function retrievePacketList(target = "all", onComplete = null) { } }, error: function(jqXHR, textStatus, errorThrown) { - log.info("Unable to load packets, trying legacy '/packets'"); + log.info("No static packets.json found, checking legacy '/packets' endpoint"); $.getJSON("packets", function(data) { if (!data.hasOwnProperty("exams")) { loadPacketList(data); } - }).fail(function(jqXHR, textStatus, errorThrown) { - console.warn("No packet list available"); + }).fail(function() { + log.info("No static local packets available, using remote exam list"); }); } - }); + }).catch(() => null); promises.push(p); } + // 2. Fetch exams if target is "all" or "exams" or one of the types if (target === "all" || target === "exams" || ["anatomy", "rapid", "short", "long"].includes(target)) { let examUrl = null; @@ -557,9 +558,10 @@ async function retrievePacketList(target = "all", onComplete = null) { if (onComplete) onComplete(true); }) .catch((err) => { - console.warn("One or more requests failed", err); + log.info("Exam or packet loading completed with fallback", err); if (onComplete) onComplete(false); }); + } else { if (onComplete) onComplete(true); } diff --git a/js/sentry.js b/js/sentry.js index a50675e..32a1259 100644 --- a/js/sentry.js +++ b/js/sentry.js @@ -10,6 +10,8 @@ export function initSentry() { const dsn = window.SENTRY_DSN || window.RTS_SENTRY_DSN || metaDsn || defaultDsn; if (!dsn) { + window.SENTRY_STATUS = { loaded: false, reason: "No DSN configured" }; + console.warn("[Sentry] ❌ Error monitoring disabled (No DSN provided)"); return; } @@ -50,6 +52,24 @@ export function initSentry() { ], }; + const onInitialized = () => { + window.SENTRY_STATUS = { loaded: true, dsn: dsn, environment: config.environment }; + console.info(`[Sentry] ✅ Error monitoring initialized (Env: ${config.environment})`); + + // Expose a convenient window.testSentry() function for testing from browser console + window.testSentry = function(msg = "RTS Sentry Test Event") { + if (window.Sentry && typeof window.Sentry.captureException === "function") { + const testErr = new Error(msg); + window.Sentry.captureException(testErr); + console.info("[Sentry] 🚀 Sent test error event to Sentry:", testErr); + return "Sentry test event sent!"; + } else { + console.error("[Sentry] ❌ Sentry is not available to send test event"); + return "Failed to send event"; + } + }; + }; + if (window.Sentry) { window.Sentry.init({ ...config, @@ -57,7 +77,7 @@ export function initSentry() { window.Sentry.browserTracingIntegration ? window.Sentry.browserTracingIntegration() : null, ].filter(Boolean), }); - console.log("[RTS] Sentry error monitoring initialized"); + onInitialized(); } else { const script = document.createElement("script"); script.src = "https://browser.sentry-cdn.com/8.48.0/bundle.min.js"; @@ -65,12 +85,17 @@ export function initSentry() { script.onload = () => { if (window.Sentry) { window.Sentry.init(config); - console.log("[RTS] Sentry error monitoring initialized via dynamic load"); + onInitialized(); } }; + script.onerror = () => { + window.SENTRY_STATUS = { loaded: false, reason: "Failed to load Sentry CDN script" }; + console.warn("[Sentry] ❌ Failed to load Sentry CDN script"); + }; document.head.appendChild(script); } } catch (err) { - console.warn("[RTS] Sentry initialization failed:", err); + window.SENTRY_STATUS = { loaded: false, error: err }; + console.warn("[Sentry] ❌ Initialization failed:", err); } }