feat: Sentry error tracking integration - #76

Open
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry
Open

feat: Sentry error tracking integration#76
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 1, 2026

Copy link
Copy Markdown
Member

Summary

  • Bundles Sentry SDK (v8.33.0) for automatic error reporting with async non-blocking delivery
  • New ErrorHandler utility replaces ~190 Logger.severe() calls across ~50 files — all errors now report to Sentry alongside console logging
  • Buffers pre-init errors (during config/data loading) and flushes them once Sentry is ready (pre_init:true tag)
  • Wraps scheduled tasks, async futures, and shutdown steps to prevent silent thread death and swallowed errors
  • Sentry config lives in config/debug.json under a "sentry" section (no separate file)
  • Auto-migration: existing config/sentry.json values are read into debug.json on first load, old file deleted
  • /f admin sentry command lets server owners view status and opt out/in at runtime
  • /f admin sentrytest sends a test event to verify the integration
  • Rich context on every event: server version, patchline, installed mods, OS, Java version, server config
  • Auto-detects environment from server patchline (release→production, pre-release→staging, dev→development)
  • Source context upload via Sentry Gradle plugin — stack traces show source code in Sentry dashboard

Test plan

  • ./gradlew :HyperFactions:compileJava compiles cleanly
  • /f admin sentrytest sends test event to Sentry dashboard
  • Malformed config/data JSON files produce errors visible in Sentry (via pre-init buffer)
  • Installed mods list appears in Sentry event context
  • Clean start: debug.json generates with "sentry" section, no sentry.json created
  • Migration: place old sentry.json in config dir, restart — values migrate into debug.json, old file deleted
  • /f admin sentry shows correct status
  • /f admin sentry disable closes Sentry and saves config
  • /f admin sentry enable re-initializes Sentry and saves config
  • Verify periodic tasks survive exceptions (scheduler threads don't die)
  • Verify shutdown completes all steps even if one fails

Non-blocking async error reporting to Sentry with fail-safe wrapping.
Includes configurable DSN, source context upload, and /f admin sentrytest command.
Config loads in enable() during start(), not setup(). Calling
ConfigManager.get().sentry() in setup() returned null.
Fix task dependency for all Sentry tasks on generateBuildInfo.
Auto-upload source bundle after every build via finalizedBy.
Tags: hytale.server.version, plugin.version, java.version, os
Context: structured server info with CPU count and max memory
Includes server_name, max_players, and MOTD from HytaleServerConfig.
Maps ManifestUtil.getPatchline() to Sentry environments:
release → production, pre-release → staging, dev → development.
Falls back to config value if detection fails.
Lists all loaded plugins with name, version, and state.
Refreshed on BootEvent for a complete picture after all plugins load.
Change HashMap type from <String, String> with unsafe double-cast to
<String, Object> which setContexts() accepts directly. Add total_count
field and debug logging for verification.
Add ErrorHandler utility class that centralizes error handling — all
errors are now logged to console AND reported to Sentry. Convert ~190
Logger.severe() calls in catch blocks across ~50 files to route through
ErrorHandler. Wrap scheduled tasks with wrapTask() to prevent silent
thread death, guard async futures, and isolate shutdown steps.
Add pre-init error buffering to SentryIntegration so errors during
config/data loading (before Sentry initializes) are captured and
flushed once Sentry is ready, tagged with pre_init:true.
Wire WriteResult.Failure storage errors (with nullable Exception cause)
through to Sentry via new report(@nullable) overload.
Move sentry configuration from standalone config/sentry.json into a
nested "sentry" section within config/debug.json. Auto-migration reads
existing sentry.json values on first load and deletes the old file.
Add /f admin sentry command for server owners to view status, opt out,
or opt back in to error reporting at runtime without editing config files.
Remove SentryConfig class, update ConfigManager, SentryIntegration, and
all callers to use DebugConfig for sentry settings.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: Sentry error tracking integration - #76

Open
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry
Open

feat: Sentry error tracking integration#76
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 1, 2026

Copy link
Copy Markdown
Member

Summary

  • Bundles Sentry SDK (v8.33.0) for automatic error reporting with async non-blocking delivery
  • New ErrorHandler utility replaces ~190 Logger.severe() calls across ~50 files — all errors now report to Sentry alongside console logging
  • Buffers pre-init errors (during config/data loading) and flushes them once Sentry is ready (pre_init:true tag)
  • Wraps scheduled tasks, async futures, and shutdown steps to prevent silent thread death and swallowed errors
  • Sentry config lives in config/debug.json under a "sentry" section (no separate file)
  • Auto-migration: existing config/sentry.json values are read into debug.json on first load, old file deleted
  • /f admin sentry command lets server owners view status and opt out/in at runtime
  • /f admin sentrytest sends a test event to verify the integration
  • Rich context on every event: server version, patchline, installed mods, OS, Java version, server config
  • Auto-detects environment from server patchline (release→production, pre-release→staging, dev→development)
  • Source context upload via Sentry Gradle plugin — stack traces show source code in Sentry dashboard

Test plan

  • ./gradlew :HyperFactions:compileJava compiles cleanly
  • /f admin sentrytest sends test event to Sentry dashboard
  • Malformed config/data JSON files produce errors visible in Sentry (via pre-init buffer)
  • Installed mods list appears in Sentry event context
  • Clean start: debug.json generates with "sentry" section, no sentry.json created
  • Migration: place old sentry.json in config dir, restart — values migrate into debug.json, old file deleted
  • /f admin sentry shows correct status
  • /f admin sentry disable closes Sentry and saves config
  • /f admin sentry enable re-initializes Sentry and saves config
  • Verify periodic tasks survive exceptions (scheduler threads don't die)
  • Verify shutdown completes all steps even if one fails

Non-blocking async error reporting to Sentry with fail-safe wrapping.
Includes configurable DSN, source context upload, and /f admin sentrytest command.
Config loads in enable() during start(), not setup(). Calling
ConfigManager.get().sentry() in setup() returned null.
Fix task dependency for all Sentry tasks on generateBuildInfo.
Auto-upload source bundle after every build via finalizedBy.
Tags: hytale.server.version, plugin.version, java.version, os
Context: structured server info with CPU count and max memory
Includes server_name, max_players, and MOTD from HytaleServerConfig.
Maps ManifestUtil.getPatchline() to Sentry environments:
release → production, pre-release → staging, dev → development.
Falls back to config value if detection fails.
Lists all loaded plugins with name, version, and state.
Refreshed on BootEvent for a complete picture after all plugins load.
Change HashMap type from <String, String> with unsafe double-cast to
<String, Object> which setContexts() accepts directly. Add total_count
field and debug logging for verification.
Add ErrorHandler utility class that centralizes error handling — all
errors are now logged to console AND reported to Sentry. Convert ~190
Logger.severe() calls in catch blocks across ~50 files to route through
ErrorHandler. Wrap scheduled tasks with wrapTask() to prevent silent
thread death, guard async futures, and isolate shutdown steps.
Add pre-init error buffering to SentryIntegration so errors during
config/data loading (before Sentry initializes) are captured and
flushed once Sentry is ready, tagged with pre_init:true.
Wire WriteResult.Failure storage errors (with nullable Exception cause)
through to Sentry via new report(@nullable) overload.
Move sentry configuration from standalone config/sentry.json into a
nested "sentry" section within config/debug.json. Auto-migration reads
existing sentry.json values on first load and deletes the old file.
Add /f admin sentry command for server owners to view status, opt out,
or opt back in to error reporting at runtime without editing config files.
Remove SentryConfig class, update ConfigManager, SentryIntegration, and
all callers to use DebugConfig for sentry settings.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Sentry error tracking integration - #76

Open
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry
Open

feat: Sentry error tracking integration#76
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 1, 2026

Copy link
Copy Markdown
Member

Summary

  • Bundles Sentry SDK (v8.33.0) for automatic error reporting with async non-blocking delivery
  • New ErrorHandler utility replaces ~190 Logger.severe() calls across ~50 files — all errors now report to Sentry alongside console logging
  • Buffers pre-init errors (during config/data loading) and flushes them once Sentry is ready (pre_init:true tag)
  • Wraps scheduled tasks, async futures, and shutdown steps to prevent silent thread death and swallowed errors
  • Sentry config lives in config/debug.json under a "sentry" section (no separate file)
  • Auto-migration: existing config/sentry.json values are read into debug.json on first load, old file deleted
  • /f admin sentry command lets server owners view status and opt out/in at runtime
  • /f admin sentrytest sends a test event to verify the integration
  • Rich context on every event: server version, patchline, installed mods, OS, Java version, server config
  • Auto-detects environment from server patchline (release→production, pre-release→staging, dev→development)
  • Source context upload via Sentry Gradle plugin — stack traces show source code in Sentry dashboard

Test plan

  • ./gradlew :HyperFactions:compileJava compiles cleanly
  • /f admin sentrytest sends test event to Sentry dashboard
  • Malformed config/data JSON files produce errors visible in Sentry (via pre-init buffer)
  • Installed mods list appears in Sentry event context
  • Clean start: debug.json generates with "sentry" section, no sentry.json created
  • Migration: place old sentry.json in config dir, restart — values migrate into debug.json, old file deleted
  • /f admin sentry shows correct status
  • /f admin sentry disable closes Sentry and saves config
  • /f admin sentry enable re-initializes Sentry and saves config
  • Verify periodic tasks survive exceptions (scheduler threads don't die)
  • Verify shutdown completes all steps even if one fails

Non-blocking async error reporting to Sentry with fail-safe wrapping.
Includes configurable DSN, source context upload, and /f admin sentrytest command.
Config loads in enable() during start(), not setup(). Calling
ConfigManager.get().sentry() in setup() returned null.
Fix task dependency for all Sentry tasks on generateBuildInfo.
Auto-upload source bundle after every build via finalizedBy.
Tags: hytale.server.version, plugin.version, java.version, os
Context: structured server info with CPU count and max memory
Includes server_name, max_players, and MOTD from HytaleServerConfig.
Maps ManifestUtil.getPatchline() to Sentry environments:
release → production, pre-release → staging, dev → development.
Falls back to config value if detection fails.
Lists all loaded plugins with name, version, and state.
Refreshed on BootEvent for a complete picture after all plugins load.
Change HashMap type from <String, String> with unsafe double-cast to
<String, Object> which setContexts() accepts directly. Add total_count
field and debug logging for verification.
Add ErrorHandler utility class that centralizes error handling — all
errors are now logged to console AND reported to Sentry. Convert ~190
Logger.severe() calls in catch blocks across ~50 files to route through
ErrorHandler. Wrap scheduled tasks with wrapTask() to prevent silent
thread death, guard async futures, and isolate shutdown steps.
Add pre-init error buffering to SentryIntegration so errors during
config/data loading (before Sentry initializes) are captured and
flushed once Sentry is ready, tagged with pre_init:true.
Wire WriteResult.Failure storage errors (with nullable Exception cause)
through to Sentry via new report(@nullable) overload.
Move sentry configuration from standalone config/sentry.json into a
nested "sentry" section within config/debug.json. Auto-migration reads
existing sentry.json values on first load and deletes the old file.
Add /f admin sentry command for server owners to view status, opt out,
or opt back in to error reporting at runtime without editing config files.
Remove SentryConfig class, update ConfigManager, SentryIntegration, and
all callers to use DebugConfig for sentry settings.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Sentry error tracking integration - #76

Open
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry
Open

feat: Sentry error tracking integration#76
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 1, 2026

Copy link
Copy Markdown
Member

Summary

  • Bundles Sentry SDK (v8.33.0) for automatic error reporting with async non-blocking delivery
  • New ErrorHandler utility replaces ~190 Logger.severe() calls across ~50 files — all errors now report to Sentry alongside console logging
  • Buffers pre-init errors (during config/data loading) and flushes them once Sentry is ready (pre_init:true tag)
  • Wraps scheduled tasks, async futures, and shutdown steps to prevent silent thread death and swallowed errors
  • Sentry config lives in config/debug.json under a "sentry" section (no separate file)
  • Auto-migration: existing config/sentry.json values are read into debug.json on first load, old file deleted
  • /f admin sentry command lets server owners view status and opt out/in at runtime
  • /f admin sentrytest sends a test event to verify the integration
  • Rich context on every event: server version, patchline, installed mods, OS, Java version, server config
  • Auto-detects environment from server patchline (release→production, pre-release→staging, dev→development)
  • Source context upload via Sentry Gradle plugin — stack traces show source code in Sentry dashboard

Test plan

  • ./gradlew :HyperFactions:compileJava compiles cleanly
  • /f admin sentrytest sends test event to Sentry dashboard
  • Malformed config/data JSON files produce errors visible in Sentry (via pre-init buffer)
  • Installed mods list appears in Sentry event context
  • Clean start: debug.json generates with "sentry" section, no sentry.json created
  • Migration: place old sentry.json in config dir, restart — values migrate into debug.json, old file deleted
  • /f admin sentry shows correct status
  • /f admin sentry disable closes Sentry and saves config
  • /f admin sentry enable re-initializes Sentry and saves config
  • Verify periodic tasks survive exceptions (scheduler threads don't die)
  • Verify shutdown completes all steps even if one fails

Non-blocking async error reporting to Sentry with fail-safe wrapping.
Includes configurable DSN, source context upload, and /f admin sentrytest command.
Config loads in enable() during start(), not setup(). Calling
ConfigManager.get().sentry() in setup() returned null.
Fix task dependency for all Sentry tasks on generateBuildInfo.
Auto-upload source bundle after every build via finalizedBy.
Tags: hytale.server.version, plugin.version, java.version, os
Context: structured server info with CPU count and max memory
Includes server_name, max_players, and MOTD from HytaleServerConfig.
Maps ManifestUtil.getPatchline() to Sentry environments:
release → production, pre-release → staging, dev → development.
Falls back to config value if detection fails.
Lists all loaded plugins with name, version, and state.
Refreshed on BootEvent for a complete picture after all plugins load.
Change HashMap type from <String, String> with unsafe double-cast to
<String, Object> which setContexts() accepts directly. Add total_count
field and debug logging for verification.
Add ErrorHandler utility class that centralizes error handling — all
errors are now logged to console AND reported to Sentry. Convert ~190
Logger.severe() calls in catch blocks across ~50 files to route through
ErrorHandler. Wrap scheduled tasks with wrapTask() to prevent silent
thread death, guard async futures, and isolate shutdown steps.
Add pre-init error buffering to SentryIntegration so errors during
config/data loading (before Sentry initializes) are captured and
flushed once Sentry is ready, tagged with pre_init:true.
Wire WriteResult.Failure storage errors (with nullable Exception cause)
through to Sentry via new report(@nullable) overload.
Move sentry configuration from standalone config/sentry.json into a
nested "sentry" section within config/debug.json. Auto-migration reads
existing sentry.json values on first load and deletes the old file.
Add /f admin sentry command for server owners to view status, opt out,
or opt back in to error reporting at runtime without editing config files.
Remove SentryConfig class, update ConfigManager, SentryIntegration, and
all callers to use DebugConfig for sentry settings.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: Sentry error tracking integration - #76

Open
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry
Open

feat: Sentry error tracking integration#76
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 1, 2026

Copy link
Copy Markdown
Member

Summary

  • Bundles Sentry SDK (v8.33.0) for automatic error reporting with async non-blocking delivery
  • New ErrorHandler utility replaces ~190 Logger.severe() calls across ~50 files — all errors now report to Sentry alongside console logging
  • Buffers pre-init errors (during config/data loading) and flushes them once Sentry is ready (pre_init:true tag)
  • Wraps scheduled tasks, async futures, and shutdown steps to prevent silent thread death and swallowed errors
  • Sentry config lives in config/debug.json under a "sentry" section (no separate file)
  • Auto-migration: existing config/sentry.json values are read into debug.json on first load, old file deleted
  • /f admin sentry command lets server owners view status and opt out/in at runtime
  • /f admin sentrytest sends a test event to verify the integration
  • Rich context on every event: server version, patchline, installed mods, OS, Java version, server config
  • Auto-detects environment from server patchline (release→production, pre-release→staging, dev→development)
  • Source context upload via Sentry Gradle plugin — stack traces show source code in Sentry dashboard

Test plan

  • ./gradlew :HyperFactions:compileJava compiles cleanly
  • /f admin sentrytest sends test event to Sentry dashboard
  • Malformed config/data JSON files produce errors visible in Sentry (via pre-init buffer)
  • Installed mods list appears in Sentry event context
  • Clean start: debug.json generates with "sentry" section, no sentry.json created
  • Migration: place old sentry.json in config dir, restart — values migrate into debug.json, old file deleted
  • /f admin sentry shows correct status
  • /f admin sentry disable closes Sentry and saves config
  • /f admin sentry enable re-initializes Sentry and saves config
  • Verify periodic tasks survive exceptions (scheduler threads don't die)
  • Verify shutdown completes all steps even if one fails

Non-blocking async error reporting to Sentry with fail-safe wrapping.
Includes configurable DSN, source context upload, and /f admin sentrytest command.
Config loads in enable() during start(), not setup(). Calling
ConfigManager.get().sentry() in setup() returned null.
Fix task dependency for all Sentry tasks on generateBuildInfo.
Auto-upload source bundle after every build via finalizedBy.
Tags: hytale.server.version, plugin.version, java.version, os
Context: structured server info with CPU count and max memory
Includes server_name, max_players, and MOTD from HytaleServerConfig.
Maps ManifestUtil.getPatchline() to Sentry environments:
release → production, pre-release → staging, dev → development.
Falls back to config value if detection fails.
Lists all loaded plugins with name, version, and state.
Refreshed on BootEvent for a complete picture after all plugins load.
Change HashMap type from <String, String> with unsafe double-cast to
<String, Object> which setContexts() accepts directly. Add total_count
field and debug logging for verification.
Add ErrorHandler utility class that centralizes error handling — all
errors are now logged to console AND reported to Sentry. Convert ~190
Logger.severe() calls in catch blocks across ~50 files to route through
ErrorHandler. Wrap scheduled tasks with wrapTask() to prevent silent
thread death, guard async futures, and isolate shutdown steps.
Add pre-init error buffering to SentryIntegration so errors during
config/data loading (before Sentry initializes) are captured and
flushed once Sentry is ready, tagged with pre_init:true.
Wire WriteResult.Failure storage errors (with nullable Exception cause)
through to Sentry via new report(@nullable) overload.
Move sentry configuration from standalone config/sentry.json into a
nested "sentry" section within config/debug.json. Auto-migration reads
existing sentry.json values on first load and deletes the old file.
Add /f admin sentry command for server owners to view status, opt out,
or opt back in to error reporting at runtime without editing config files.
Remove SentryConfig class, update ConfigManager, SentryIntegration, and
all callers to use DebugConfig for sentry settings.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Sentry error tracking integration - #76

Open
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry
Open

feat: Sentry error tracking integration#76
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 1, 2026

Copy link
Copy Markdown
Member

Summary

  • Bundles Sentry SDK (v8.33.0) for automatic error reporting with async non-blocking delivery
  • New ErrorHandler utility replaces ~190 Logger.severe() calls across ~50 files — all errors now report to Sentry alongside console logging
  • Buffers pre-init errors (during config/data loading) and flushes them once Sentry is ready (pre_init:true tag)
  • Wraps scheduled tasks, async futures, and shutdown steps to prevent silent thread death and swallowed errors
  • Sentry config lives in config/debug.json under a "sentry" section (no separate file)
  • Auto-migration: existing config/sentry.json values are read into debug.json on first load, old file deleted
  • /f admin sentry command lets server owners view status and opt out/in at runtime
  • /f admin sentrytest sends a test event to verify the integration
  • Rich context on every event: server version, patchline, installed mods, OS, Java version, server config
  • Auto-detects environment from server patchline (release→production, pre-release→staging, dev→development)
  • Source context upload via Sentry Gradle plugin — stack traces show source code in Sentry dashboard

Test plan

  • ./gradlew :HyperFactions:compileJava compiles cleanly
  • /f admin sentrytest sends test event to Sentry dashboard
  • Malformed config/data JSON files produce errors visible in Sentry (via pre-init buffer)
  • Installed mods list appears in Sentry event context
  • Clean start: debug.json generates with "sentry" section, no sentry.json created
  • Migration: place old sentry.json in config dir, restart — values migrate into debug.json, old file deleted
  • /f admin sentry shows correct status
  • /f admin sentry disable closes Sentry and saves config
  • /f admin sentry enable re-initializes Sentry and saves config
  • Verify periodic tasks survive exceptions (scheduler threads don't die)
  • Verify shutdown completes all steps even if one fails

Non-blocking async error reporting to Sentry with fail-safe wrapping.
Includes configurable DSN, source context upload, and /f admin sentrytest command.
Config loads in enable() during start(), not setup(). Calling
ConfigManager.get().sentry() in setup() returned null.
Fix task dependency for all Sentry tasks on generateBuildInfo.
Auto-upload source bundle after every build via finalizedBy.
Tags: hytale.server.version, plugin.version, java.version, os
Context: structured server info with CPU count and max memory
Includes server_name, max_players, and MOTD from HytaleServerConfig.
Maps ManifestUtil.getPatchline() to Sentry environments:
release → production, pre-release → staging, dev → development.
Falls back to config value if detection fails.
Lists all loaded plugins with name, version, and state.
Refreshed on BootEvent for a complete picture after all plugins load.
Change HashMap type from <String, String> with unsafe double-cast to
<String, Object> which setContexts() accepts directly. Add total_count
field and debug logging for verification.
Add ErrorHandler utility class that centralizes error handling — all
errors are now logged to console AND reported to Sentry. Convert ~190
Logger.severe() calls in catch blocks across ~50 files to route through
ErrorHandler. Wrap scheduled tasks with wrapTask() to prevent silent
thread death, guard async futures, and isolate shutdown steps.
Add pre-init error buffering to SentryIntegration so errors during
config/data loading (before Sentry initializes) are captured and
flushed once Sentry is ready, tagged with pre_init:true.
Wire WriteResult.Failure storage errors (with nullable Exception cause)
through to Sentry via new report(@nullable) overload.
Move sentry configuration from standalone config/sentry.json into a
nested "sentry" section within config/debug.json. Auto-migration reads
existing sentry.json values on first load and deletes the old file.
Add /f admin sentry command for server owners to view status, opt out,
or opt back in to error reporting at runtime without editing config files.
Remove SentryConfig class, update ConfigManager, SentryIntegration, and
all callers to use DebugConfig for sentry settings.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Sentry error tracking integration - #76

Open
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry
Open

feat: Sentry error tracking integration#76
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 1, 2026

Copy link
Copy Markdown
Member

Summary

  • Bundles Sentry SDK (v8.33.0) for automatic error reporting with async non-blocking delivery
  • New ErrorHandler utility replaces ~190 Logger.severe() calls across ~50 files — all errors now report to Sentry alongside console logging
  • Buffers pre-init errors (during config/data loading) and flushes them once Sentry is ready (pre_init:true tag)
  • Wraps scheduled tasks, async futures, and shutdown steps to prevent silent thread death and swallowed errors
  • Sentry config lives in config/debug.json under a "sentry" section (no separate file)
  • Auto-migration: existing config/sentry.json values are read into debug.json on first load, old file deleted
  • /f admin sentry command lets server owners view status and opt out/in at runtime
  • /f admin sentrytest sends a test event to verify the integration
  • Rich context on every event: server version, patchline, installed mods, OS, Java version, server config
  • Auto-detects environment from server patchline (release→production, pre-release→staging, dev→development)
  • Source context upload via Sentry Gradle plugin — stack traces show source code in Sentry dashboard

Test plan

  • ./gradlew :HyperFactions:compileJava compiles cleanly
  • /f admin sentrytest sends test event to Sentry dashboard
  • Malformed config/data JSON files produce errors visible in Sentry (via pre-init buffer)
  • Installed mods list appears in Sentry event context
  • Clean start: debug.json generates with "sentry" section, no sentry.json created
  • Migration: place old sentry.json in config dir, restart — values migrate into debug.json, old file deleted
  • /f admin sentry shows correct status
  • /f admin sentry disable closes Sentry and saves config
  • /f admin sentry enable re-initializes Sentry and saves config
  • Verify periodic tasks survive exceptions (scheduler threads don't die)
  • Verify shutdown completes all steps even if one fails

Non-blocking async error reporting to Sentry with fail-safe wrapping.
Includes configurable DSN, source context upload, and /f admin sentrytest command.
Config loads in enable() during start(), not setup(). Calling
ConfigManager.get().sentry() in setup() returned null.
Fix task dependency for all Sentry tasks on generateBuildInfo.
Auto-upload source bundle after every build via finalizedBy.
Tags: hytale.server.version, plugin.version, java.version, os
Context: structured server info with CPU count and max memory
Includes server_name, max_players, and MOTD from HytaleServerConfig.
Maps ManifestUtil.getPatchline() to Sentry environments:
release → production, pre-release → staging, dev → development.
Falls back to config value if detection fails.
Lists all loaded plugins with name, version, and state.
Refreshed on BootEvent for a complete picture after all plugins load.
Change HashMap type from <String, String> with unsafe double-cast to
<String, Object> which setContexts() accepts directly. Add total_count
field and debug logging for verification.
Add ErrorHandler utility class that centralizes error handling — all
errors are now logged to console AND reported to Sentry. Convert ~190
Logger.severe() calls in catch blocks across ~50 files to route through
ErrorHandler. Wrap scheduled tasks with wrapTask() to prevent silent
thread death, guard async futures, and isolate shutdown steps.
Add pre-init error buffering to SentryIntegration so errors during
config/data loading (before Sentry initializes) are captured and
flushed once Sentry is ready, tagged with pre_init:true.
Wire WriteResult.Failure storage errors (with nullable Exception cause)
through to Sentry via new report(@nullable) overload.
Move sentry configuration from standalone config/sentry.json into a
nested "sentry" section within config/debug.json. Auto-migration reads
existing sentry.json values on first load and deletes the old file.
Add /f admin sentry command for server owners to view status, opt out,
or opt back in to error reporting at runtime without editing config files.
Remove SentryConfig class, update ConfigManager, SentryIntegration, and
all callers to use DebugConfig for sentry settings.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@derrickmehaffy
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: Sentry error tracking integration - #76

Open
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry
Open

feat: Sentry error tracking integration#76
derrickmehaffy wants to merge 10 commits into
mainfrom
feat/sentry

Conversation

@derrickmehaffy

@derrickmehaffyderrickmehaffy commented Mar 1, 2026

Copy link
Copy Markdown
Member

Summary

  • Bundles Sentry SDK (v8.33.0) for automatic error reporting with async non-blocking delivery
  • New ErrorHandler utility replaces ~190 Logger.severe() calls across ~50 files — all errors now report to Sentry alongside console logging
  • Buffers pre-init errors (during config/data loading) and flushes them once Sentry is ready (pre_init:true tag)
  • Wraps scheduled tasks, async futures, and shutdown steps to prevent silent thread death and swallowed errors
  • Sentry config lives in config/debug.json under a "sentry" section (no separate file)
  • Auto-migration: existing config/sentry.json values are read into debug.json on first load, old file deleted
  • /f admin sentry command lets server owners view status and opt out/in at runtime
  • /f admin sentrytest sends a test event to verify the integration
  • Rich context on every event: server version, patchline, installed mods, OS, Java version, server config
  • Auto-detects environment from server patchline (release→production, pre-release→staging, dev→development)
  • Source context upload via Sentry Gradle plugin — stack traces show source code in Sentry dashboard

Test plan

  • ./gradlew :HyperFactions:compileJava compiles cleanly
  • /f admin sentrytest sends test event to Sentry dashboard
  • Malformed config/data JSON files produce errors visible in Sentry (via pre-init buffer)
  • Installed mods list appears in Sentry event context
  • Clean start: debug.json generates with "sentry" section, no sentry.json created
  • Migration: place old sentry.json in config dir, restart — values migrate into debug.json, old file deleted
  • /f admin sentry shows correct status
  • /f admin sentry disable closes Sentry and saves config
  • /f admin sentry enable re-initializes Sentry and saves config
  • Verify periodic tasks survive exceptions (scheduler threads don't die)
  • Verify shutdown completes all steps even if one fails

Non-blocking async error reporting to Sentry with fail-safe wrapping.
Includes configurable DSN, source context upload, and /f admin sentrytest command.
Config loads in enable() during start(), not setup(). Calling
ConfigManager.get().sentry() in setup() returned null.
Fix task dependency for all Sentry tasks on generateBuildInfo.
Auto-upload source bundle after every build via finalizedBy.
Tags: hytale.server.version, plugin.version, java.version, os
Context: structured server info with CPU count and max memory
Includes server_name, max_players, and MOTD from HytaleServerConfig.
Maps ManifestUtil.getPatchline() to Sentry environments:
release → production, pre-release → staging, dev → development.
Falls back to config value if detection fails.
Lists all loaded plugins with name, version, and state.
Refreshed on BootEvent for a complete picture after all plugins load.
Change HashMap type from <String, String> with unsafe double-cast to
<String, Object> which setContexts() accepts directly. Add total_count
field and debug logging for verification.
Add ErrorHandler utility class that centralizes error handling — all
errors are now logged to console AND reported to Sentry. Convert ~190
Logger.severe() calls in catch blocks across ~50 files to route through
ErrorHandler. Wrap scheduled tasks with wrapTask() to prevent silent
thread death, guard async futures, and isolate shutdown steps.
Add pre-init error buffering to SentryIntegration so errors during
config/data loading (before Sentry initializes) are captured and
flushed once Sentry is ready, tagged with pre_init:true.
Wire WriteResult.Failure storage errors (with nullable Exception cause)
through to Sentry via new report(@nullable) overload.
Move sentry configuration from standalone config/sentry.json into a
nested "sentry" section within config/debug.json. Auto-migration reads
existing sentry.json values on first load and deletes the old file.
Add /f admin sentry command for server owners to view status, opt out,
or opt back in to error reporting at runtime without editing config files.
Remove SentryConfig class, update ConfigManager, SentryIntegration, and
all callers to use DebugConfig for sentry settings.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@derrickmehaffy