<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Discover the latest posts and articles on Nick's Blog. Stay updated with trending topics, tips, and insights.]]></title><description><![CDATA[Discover the latest posts and articles on Nick's Blog. Stay updated with trending topics, tips, and insights.]]></description><link>https://hoainho.hashnode.dev</link><image><url>https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/logos/642f915219dd2f34ad7fa2e7/235618ee-eab7-442e-911b-929e8ace9d75.jpg</url><title>Discover the latest posts and articles on Nick&apos;s Blog. Stay updated with trending topics, tips, and insights.</title><link>https://hoainho.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 30 Oct 2026 13:04:03 GMT</lastBuildDate><atom:link href="https://hoainho.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Your Error Dashboard Is Lying to You — Here's What It's Not Showing]]></title><description><![CDATA[Stack traces tell you WHERE your app crashed. CrashSense tells you WHY — with root cause classification, confidence scoring, and AI-powered fix…]]></description><link>https://hoainho.hashnode.dev/your-error-dashboard-is-lying-to-you-here-s-what-it-s-not-showing</link><guid isPermaLink="true">https://hoainho.hashnode.dev/your-error-dashboard-is-lying-to-you-here-s-what-it-s-not-showing</guid><category><![CDATA[react js]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[debugging]]></category><category><![CDATA[tips]]></category><category><![CDATA[trends]]></category><dc:creator><![CDATA[Hoài Nhớ]]></dc:creator><pubDate>Mon, 23 Feb 2026 11:07:23 GMT</pubDate><enclosure url="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/642f915219dd2f34ad7fa2e7/f41f7242-33d9-4f2b-8520-58c72bc6b7f6.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>The 2am Call That Started Everything</h2>
<p>It was 2am on a Thursday. Our checkout page was crashing in production.</p>
<p>I opened Sentry. It showed me this:</p>
<pre><code class="language-plaintext">TypeError: Cannot read properties of undefined (reading 'map')
    at UserList (UserList.tsx:42)
    at renderWithHooks (react-dom.development.js:14985)
</code></pre>
<p>Five engineers on a call. One shared their screen. One opened the logs. One blamed the last PR. Two were silently Googling.</p>
<p>Three hours later, we found it — a <code>useEffect</code> missing a cleanup function. The heap quietly climbed to 92%, the garbage collector gave up, and a perfectly healthy <code>.map()</code> became the scapegoat.</p>
<p>The stack trace knew exactly <strong>where</strong> it happened. It had absolutely no idea <strong>why</strong>.</p>
<img alt="A frustrated developer staring at a red error on their monitor at 2am, dark room with blue screen glow" style="display:block;margin:0 auto" />

<hr />
<h2>The Gap Nobody Talks About</h2>
<p>Here's the dirty secret of frontend error monitoring:</p>
<p><strong>Every tool on the market does the same thing</strong> — captures the exception, groups it by stack trace, sends you a Slack alert. Then it's your problem.</p>
<p>You still have to figure out:</p>
<ul>
<li><p>Is this a race condition?</p>
</li>
<li><p>A failed API call?</p>
</li>
<li><p>A memory leak?</p>
</li>
<li><p>A hydration mismatch?</p>
</li>
</ul>
<p>You don't know. The tool doesn't know. Enjoy your next 3 hours of detective work.</p>
<p>I asked myself a simple question that night:</p>
<blockquote>
<p>Why does every error tool tell me WHAT crashed, but none of them tell me WHY?</p>
</blockquote>
<hr />
<h2>Introducing CrashSense</h2>
<p><strong>CrashSense</strong> is a crash <em>diagnosis</em> SDK — not another error tracker.</p>
<p>That same TypeError? CrashSense returns this:</p>
<pre><code class="language-js">{
  category: "memory_issue",
  subcategory: "memory_leak",
  confidence: 0.87,
  severity: "critical",

  contributingFactors: [
    { factor: "high_memory_utilization", weight: 0.9,
      evidence: "Heap at 92% (487MB / 528MB)" },
    { factor: "memory_growing_trend", weight: 0.8,
      evidence: "Heap growing at 2.3MB/s over 60s" },
    { factor: "high_long_task_count", weight: 0.6,
      evidence: "4 long tasks in last 30s (avg 340ms)" },
  ],

  breadcrumbs: [
    { type: "navigation", message: "User navigated to /checkout" },
    { type: "click", message: "User clicked 'Add to Cart'" },
    { type: "network", message: "POST /api/cart → 200 (142ms)" },
    { type: "console", message: "Warning: memory pressure elevated" },
  ],

  aiAnalysis: {
    rootCause: "Memory leak in useEffect — event listener not cleaned up",
    fix: { code: "return () =&gt; window.removeEventListener('resize', handler);" },
    prevention: "Always return cleanup functions from useEffect with side effects",
  }
}
</code></pre>
<p><strong>Root cause classified. Evidence chain provided. Fix suggested.</strong></p>
<p>The junior on call could've resolved it. At 2:01am. Without waking anyone up.</p>
<img src="https://raw.githubusercontent.com/hoainho/crashsense/main/blog/02-crashsense-output.png" alt="CrashSense output showing classified crash report with confidence score and AI fix suggestion" style="display:block;margin:0 auto" />

<hr />
<h2>How It Actually Works — Under the Hood</h2>
<p>CrashSense isn't magic. It's a classification engine that correlates system signals with error patterns in real-time.</p>
<h3>1. Continuous System Monitoring</h3>
<p>The SDK passively monitors 4 system dimensions using native browser APIs:</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><th><p>Monitor</p></th><th><p>API Used</p></th><th><p>What It Tracks</p></th></tr><tr><td><p><strong>Memory</strong></p></td><td><p><code>performance.memory</code></p></td><td><p>Heap usage, utilization %, growth trend</p></td></tr><tr><td><p><strong>Event Loop</strong></p></td><td><p><code>PerformanceObserver</code> (Long Task)</p></td><td><p>Blocking tasks, frame timing</p></td></tr><tr><td><p><strong>Network</strong></p></td><td><p><code>fetch</code>/<code>XHR</code> interception</p></td><td><p>Failed requests, timeouts, offline state</p></td></tr><tr><td><p><strong>Iframe</strong></p></td><td><p><code>MutationObserver</code></p></td><td><p>Iframe count, cross-origin detection</p></td></tr></tbody></table>

<p>All monitoring is passive — no monkey-patching, no proxy wrapping. CPU overhead stays under 2%.</p>
<h3>2. Multi-Signal Classification</h3>
<p>When an error occurs, the classifier doesn't just look at the error message. It correlates the error with the current system state:</p>
<pre><code class="language-plaintext">Error: TypeError (reading 'map')
  + Memory at 92% and growing     → memory_issue signal
  + 4 long tasks in last 30s      → event_loop signal
  + 0 network failures            → not network_induced
  + React component stack present  → check framework_react
</code></pre>
<p>Each signal gets a <strong>weight</strong> based on evidence strength. The category with the highest weighted score wins, and the confidence reflects how sure the system is.</p>
<p><strong>7 crash categories:</strong></p>
<table style="min-width:50px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><th><p>Category</p></th><th><p>What It Catches</p></th></tr><tr><td><p><code>memory_issue</code></p></td><td><p>Memory leaks, heap spikes, OOM</p></td></tr><tr><td><p><code>event_loop_blocking</code></p></td><td><p>Infinite loops, frozen UI, long tasks</p></td></tr><tr><td><p><code>framework_react</code></p></td><td><p>Hydration mismatches, infinite re-renders, hook violations</p></td></tr><tr><td><p><code>framework_vue</code></p></td><td><p>Reactivity loops, watcher cascades, lifecycle errors</p></td></tr><tr><td><p><code>network_induced</code></p></td><td><p>Offline crashes, CORS blocks, timeout cascades</p></td></tr><tr><td><p><code>iframe_overload</code></p></td><td><p>Excessive iframes exhausting memory</p></td></tr><tr><td><p><code>runtime_error</code></p></td><td><p>TypeError, ReferenceError, RangeError</p></td></tr></tbody></table>

<h3>3. Breadcrumb Trail</h3>
<p>Every user interaction is automatically recorded — clicks, navigation, network requests, console output, state changes. When the crash report lands, you're reading a <strong>timeline</strong>, not a stack trace.</p>
<h3>4. AI Fix Suggestions (Optional)</h3>
<p>Plug in your own LLM (OpenAI, Anthropic, Google, or any compatible endpoint). CrashSense sends a structured, token-optimized crash payload and returns parsed root cause analysis with fix code.</p>
<img src="https://raw.githubusercontent.com/hoainho/crashsense/main/blog/03-architecture.png" alt="Architecture diagram showing CrashSense monitoring pipeline" style="display:block;margin:0 auto" />

<hr />
<h2>Setup in 60 Seconds</h2>
<h3>Core (Vanilla JS / Any Framework)</h3>
<pre><code class="language-bash">npm install @crashsense/core
</code></pre>
<pre><code class="language-ts">import { createCrashSense } from '@crashsense/core';

const cs = createCrashSense({
  appId: 'my-app',
  onCrash: (report) =&gt; {
    console.log(report.event.category);     // "memory_issue"
    console.log(report.event.confidence);   // 0.87
    console.log(report.event.contributingFactors);
  },
});
</code></pre>
<p>That's it. Memory, event loop, network — all monitored. Every crash classified.</p>
<h3>React — 3 Lines</h3>
<pre><code class="language-bash">npm install @crashsense/core @crashsense/react
</code></pre>
<pre><code class="language-tsx">import { CrashSenseProvider } from '@crashsense/react';

function App() {
  return (
    &lt;CrashSenseProvider
      config={{ appId: 'my-app' }}
      onCrash={(report) =&gt; console.log(report)}
    &gt;
      &lt;YourApp /&gt;
    &lt;/CrashSenseProvider&gt;
  );
}
</code></pre>
<p>Automatically catches: hydration mismatches, infinite re-render loops, hook ordering violations.</p>
<p><strong>Hooks for granular control:</strong></p>
<pre><code class="language-tsx">import { useCrashSense, useRenderTracker } from '@crashsense/react';

function Checkout() {
  const { captureException, addBreadcrumb } = useCrashSense();
  useRenderTracker('Checkout');

  const handlePay = async () =&gt; {
    addBreadcrumb({ type: 'click', message: 'User clicked pay' });
    try { await processPayment(); }
    catch (err) { captureException(err, { action: 'payment' }); }
  };

  return &lt;button onClick={handlePay}&gt;Pay Now&lt;/button&gt;;
}
</code></pre>
<h3>Vue — Plugin + Composables</h3>
<pre><code class="language-bash">npm install @crashsense/core @crashsense/vue
</code></pre>
<pre><code class="language-ts">import { createApp } from 'vue';
import { crashSensePlugin } from '@crashsense/vue';

const app = createApp(App);
app.use(crashSensePlugin, { appId: 'my-app' });
app.mount('#app');
</code></pre>
<p>Catches: reactivity loops, lifecycle errors, component failures via <code>app.config.errorHandler</code>.</p>
<h3>AI Integration — Bring Your Own LLM</h3>
<pre><code class="language-bash">npm install @crashsense/ai
</code></pre>
<pre><code class="language-ts">import { createAIClient } from '@crashsense/ai';

const ai = createAIClient({
  endpoint: 'https://api.openai.com/v1/chat/completions',
  apiKey: process.env.OPENAI_API_KEY!,
  model: 'gpt-4',
});

const analysis = await ai.analyze(report.event);
console.log(analysis?.rootCause);
console.log(analysis?.fix?.code);
</code></pre>
<hr />
<h2>Pre-Crash Warnings — Know Before It Dies</h2>
<p>This is the feature I'm most proud of.</p>
<p>CrashSense doesn't just tell you <strong>after</strong> the crash. It detects dangerous conditions <strong>before</strong> the browser tab dies:</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><th><p>Level</p></th><th><p>Memory Trigger</p></th><th><p>Meaning</p></th></tr><tr><td><p><code>elevated</code></p></td><td><p>&gt; 70% heap</p></td><td><p>System under pressure</p></td></tr><tr><td><p><code>critical</code></p></td><td><p>&gt; 85% heap</p></td><td><p>High risk — take action</p></td></tr><tr><td><p><code>imminent</code></p></td><td><p>&gt; 95% heap</p></td><td><p>Crash likely seconds away</p></td></tr></tbody></table>

<pre><code class="language-ts">const cs = createCrashSense({
  appId: 'my-app',
  enablePreCrashWarning: true,
  enableMemoryMonitoring: true,
});
</code></pre>
<p>Warnings are recorded as breadcrumbs. When the crash happens, the report shows the full escalation path: <code>elevated → critical → imminent → crash</code>.</p>
<p>Your app <strong>knew</strong> it was about to die. Now you can act on that.</p>
<img src="https://raw.githubusercontent.com/hoainho/crashsense/main/blog/04-pre-crash-warnings.png" alt="Pre-crash warning escalation timeline" style="display:block;margin:0 auto" />

<hr />
<h2>The Hard Constraints</h2>
<p>Building a monitoring SDK sounds straightforward until you face the real constraints:</p>
<p><strong>1. The SDK must never crash your app.</strong> One unhandled exception in your monitoring code, and you've made the problem worse. Every CrashSense operation runs inside defensive error boundaries.</p>
<p><strong>2. Bundle size matters.</strong> Teams won't adopt an 80KB monitoring SDK. CrashSense core is <strong>~7KB gzipped</strong> with <strong>zero runtime dependencies</strong>.</p>
<p><strong>3. PII must die at the SDK level.</strong> Not on your server. Not "eventually." Emails, IPs, auth tokens, and credit card numbers are auto-scrubbed <strong>before</strong> any data leaves the browser. GDPR compliance starts at the source.</p>
<p><strong>4. False positives destroy trust.</strong> Every classification has a confidence score (0.0–1.0) with evidence strings. If the system isn't sure, it says so.</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><th><p>Package</p></th><th><p>Size</p></th><th><p>Dependencies</p></th></tr><tr><td><p><code>@crashsense/core</code></p></td><td><p>~7KB</p></td><td><p>0</p></td></tr><tr><td><p><code>@crashsense/react</code></p></td><td><p>~1.3KB</p></td><td><p>0 (peer: react)</p></td></tr><tr><td><p><code>@crashsense/vue</code></p></td><td><p>~1.2KB</p></td><td><p>0 (peer: vue)</p></td></tr><tr><td><p><code>@crashsense/ai</code></p></td><td><p>~3.1KB</p></td><td><p>0</p></td></tr></tbody></table>

<hr />
<h2>CrashSense vs. The Rest</h2>
<table style="min-width:125px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><th><p>Capability</p></th><th><p>CrashSense</p></th><th><p>Sentry</p></th><th><p>LogRocket</p></th><th><p>Bugsnag</p></th></tr><tr><td><p>Root cause classification</p></td><td><p>✅ 7 categories</p></td><td><p>❌ Stack trace only</p></td><td><p>❌</p></td><td><p>❌</p></td></tr><tr><td><p>Memory leak detection</p></td><td><p>✅ Trends + utilization</p></td><td><p>❌</p></td><td><p>❌</p></td><td><p>❌</p></td></tr><tr><td><p>Pre-crash warnings</p></td><td><p>✅ 3-tier escalation</p></td><td><p>❌</p></td><td><p>❌</p></td><td><p>❌</p></td></tr><tr><td><p>AI fix suggestions</p></td><td><p>✅ Bring your LLM</p></td><td><p>❌</p></td><td><p>❌</p></td><td><p>❌</p></td></tr><tr><td><p>PII auto-scrubbing</p></td><td><p>✅ SDK-level</p></td><td><p>⚠️ Server-side</p></td><td><p>❌</p></td><td><p>⚠️</p></td></tr><tr><td><p>Bundle size</p></td><td><p><strong>~7KB</strong></p></td><td><p>~30KB</p></td><td><p>~80KB</p></td><td><p>~15KB</p></td></tr><tr><td><p>Runtime dependencies</p></td><td><p><strong>0</strong></p></td><td><p>Multiple</p></td><td><p>Multiple</p></td><td><p>Multiple</p></td></tr><tr><td><p>Pricing</p></td><td><p><strong>Free forever</strong></p></td><td><p>Free tier</p></td><td><p>\(99/mo</p></td><td><p>\)59/mo</p></td></tr></tbody></table>

<hr />
<h2>What's Next</h2>
<p><strong>v1.1.0</strong> is already out with <strong>OOM Recovery Detection</strong> — when the browser kills a tab due to memory exhaustion, CrashSense recovers the full crash context on the next page load using <code>sessionStorage</code> snapshots and a 6-signal analysis engine.</p>
<p>On the roadmap:</p>
<ul>
<li><p>Source map support for production stack traces</p>
</li>
<li><p>Dashboard UI for crash analytics</p>
</li>
<li><p>More framework adapters (Svelte, Solid)</p>
</li>
<li><p>Webhook integrations (Slack, Discord, PagerDuty)</p>
</li>
</ul>
<hr />
<h2>Try It</h2>
<pre><code class="language-bash">npm install @crashsense/core
</code></pre>
<p><strong>Links:</strong></p>
<ul>
<li><p>🔗 <a href="https://github.com/hoainho/crashsense">GitHub</a> — star it if it saves you debugging time</p>
</li>
<li><p>📖 <a href="https://crashsense.github.io/crashsense/">Documentation</a> — full API reference, guides, examples</p>
</li>
<li><p>📦 <a href="https://www.npmjs.com/package/@crashsense/core">npm</a> — <code>@crashsense/core</code>, <code>@crashsense/react</code>, <code>@crashsense/vue</code>, <code>@crashsense/ai</code></p>
</li>
</ul>
<p>Free. MIT licensed. Zero vendor lock-in.</p>
<hr />
<p><em>Built by</em> <a href="https://github.com/hoainho"><em>Hoai Nho</em></a> <em>— a tech lead who got tired of being the detective at 2am.</em></p>
]]></content:encoded></item></channel></rss>