Skip to content
Edgar Mesquita edited this page Feb 8, 2026 · 4 revisions

Debugging & Development Tools

eQuantic.UI provides professional debugging tools similar to Next.js, with development-only features that help you identify and fix issues quickly.

🔍 Development Mode Detection

The framework automatically detects the environment using IWebHostEnvironment.IsDevelopment() and exposes it to the browser via:

window.__EQ_DEV__; // true in development, false in production

All development tools are conditionally loaded based on this flag.

📝 Logger System

The logger provides consistent, prefixed logging that only outputs in development mode.

Usage

import { logger } from "@equantic/ui-runtime";

// Development only (silenced in production)
logger.debug("Component state:", state);
logger.info("API call completed");

// Always logs (even in production)
logger.warn("Deprecated API used");
logger.error("Failed to load data:", error);

Log Levels

Method Output Production Prefix
debug() Console debug ❌ Silenced [eQuantic.UI]
info() Console info ❌ Silenced [eQuantic.UI]
warn() Console warn ✅ Always [eQuantic.UI]
error() Console error ✅ Always [eQuantic.UI]

Filtering Logs

In browser DevTools, you can filter by the prefix:

[eQuantic.UI]

Implementation

The logger is implemented in src/eQuantic.UI.Runtime/src/utils/logger.ts:

const isDev = typeof window !== "undefined" && window.__EQ_DEV__;

export const logger = {
  debug(...args: any[]) {
    if (isDev) console.debug("[eQuantic.UI]", ...args);
  },

  info(...args: any[]) {
    if (isDev) console.info("[eQuantic.UI]", ...args);
  },

  warn(...args: any[]) {
    console.warn("[eQuantic.UI]", ...args);
  },

  error(...args: any[]) {
    console.error("[eQuantic.UI]", ...args);
  },
};

🚨 Error Overlay

The error overlay provides a full-screen, Next.js-style error UI that appears automatically when runtime errors occur.

Features

  • Automatic Capture: Catches unhandled errors and promise rejections
  • Stack Traces: Shows full error context with source information
  • Keyboard Support: Press Esc to close
  • Development Only: Never appears in production
  • Clean UX: Red header, monospace font, scrollable content

When It Appears

The error overlay automatically displays for:

  1. Unhandled Errors: Any uncaught exception in JavaScript
  2. Promise Rejections: Unhandled async errors
// These will trigger the error overlay in dev mode
throw new Error("Something went wrong");

Promise.reject("Async error");

await fetch("/api/data"); // If fetch fails and not caught

Error Overlay UI

┌─────────────────────────────────────────────┐
│ ⚠️ Build Error                    Close (Esc)│
├─────────────────────────────────────────────┤
│                                             │
│ Error message here                          │
│                                             │
│ ┌─────────────────────────────────────────┐ │
│ │ Stack trace:                            │ │
│ │   at MyComponent.render (page.js:42)    │ │
│ │   at Reconciler.patch (reconciler.js:12)│ │
│ │   ...                                   │ │
│ └─────────────────────────────────────────┘ │
│                                             │
├─────────────────────────────────────────────┤
│ This error overlay only appears in          │
│ development. Fix the error to continue.     │
└─────────────────────────────────────────────┘

Manual Error Display

You can manually show errors in the overlay:

import { errorOverlay } from "@equantic/ui-runtime/dev";

if (window.__EQ_DEV__) {
  errorOverlay.show({
    message: "Custom error message",
    stack: error.stack,
    componentStack: "Component hierarchy...",
  });
}

Clearing the Overlay

// Programmatically clear
errorOverlay.clear();

// User actions
// - Press Esc key
// - Click "Close" button

Implementation

The error overlay is implemented in src/eQuantic.UI.Runtime/src/dev/error-overlay.ts:

class ErrorOverlay {
  private overlay: HTMLDivElement | null = null;
  private errors: ErrorInfo[] = [];

  show(error: ErrorInfo) {
    if (!window.__EQ_DEV__) return; // Dev only

    this.errors.push(error);
    this.render();
  }

  clear() {
    this.errors = [];
    if (this.overlay) {
      this.overlay.remove();
      this.overlay = null;
    }
  }

  private render() {
    // Creates full-screen overlay with error details
  }
}

export const errorOverlay = new ErrorOverlay();

// Auto-capture errors
if (window.__EQ_DEV__) {
  window.addEventListener("error", (event) => {
    errorOverlay.show({
      message: event.message,
      stack: event.error?.stack,
    });
  });

  window.addEventListener("unhandledrejection", (event) => {
    errorOverlay.show({
      message: `Unhandled Promise Rejection: ${event.reason}`,
      stack: event.reason?.stack,
    });
  });
}

🛠️ Debugging Components

Browser DevTools

eQuantic.UI generates source maps for debugging C# code in the browser.

Chrome DevTools:

  1. Open DevTools (F12)
  2. Go to Sources tab
  3. Find webpack:// or file paths in the tree
  4. Set breakpoints directly in TypeScript/C# source
  5. Inspect state, props, and local variables

Source Maps

The compiler generates V3 source maps that map JavaScript back to original C# source:

{
  "version": 3,
  "sources": ["Page.cs"],
  "mappings": "AAAA;AACA;...",
  "names": ["MyComponent", "Render", "state"]
}

This allows you to:

  • Set breakpoints in C# code
  • Step through C# logic
  • Inspect C# variable names
  • See original line numbers in stack traces

Component Inspection

To inspect component state and props:

// In browser console
window.__EQ_DEBUG = true; // Enable debug mode

// Components expose their state
const component = document.querySelector(
  '[data-component-id="abc"]',
).__component;
console.log(component.state);
console.log(component.props);

🧪 Testing & Debugging

Integration Tests with Playwright

For debugging SSR vs CSR rendering issues:

test("SSR matches CSR", async ({ page }) => {
  // Get SSR HTML
  const ssrResponse = await page.goto("http://localhost:5000");
  const ssrHtml = await ssrResponse.text();

  // Wait for CSR hydration
  await page.waitForLoadState("networkidle");
  const csrHtml = await page.content();

  // Compare
  expect(normalizeHtml(ssrHtml)).toBe(normalizeHtml(csrHtml));
});

Server-Side Debugging

Debug C# code normally with Visual Studio or VS Code:

  1. Set breakpoints in .cs files
  2. Run with debugger attached: dotnet run
  3. Breakpoints hit during:
    • Server-side rendering (SSR)
    • Server Action invocations
    • Component compilation

Network Debugging

Monitor Server Actions in browser DevTools:

  1. Open Network tab
  2. Filter by _equantic/actions
  3. Inspect:
    • Request payload (method name, arguments)
    • Response data
    • Timing information
    • Errors (with stack traces)

Asset Provider Debugging

When using IRequireAssets, verify that dependencies are correctly injected:

  1. Inspect Source: Open browser "View Page Source" and search for the script/style tags.
  2. Network Tab: Check if the external URLs (e.g., CDNs) are loading successfully (Status 200).
  3. Deduplication: Verify that multiple components didn't inject the same script twice.
  4. Order: Stylesheets should appear before scripts for proper rendering.

Server-Side Rendering (SSR) Assets

If assets are missing in the initial HTML:

  1. Verify the component implements IRequireAssets.
  2. Ensure AddUI() is called in Program.cs.
  3. Check if the AssetCollection is correctly gathering the assets during the render pass.

📊 Performance Debugging

Runtime Performance

The reconciler tracks performance metrics in development mode:

// Enable performance tracking
window.__EQ_PERF = true;

// View metrics
console.table(window.__EQ_PERF_DATA);

Metrics include:

  • Render Time: How long each component took to render
  • Diff Time: Time spent in reconciler
  • DOM Operations: Number of actual DOM changes
  • Event Listeners: Active listener count

Build Performance

Monitor compilation times:

dotnet build -v:detailed

Look for:

  • CompileEQuanticUI target duration
  • Number of components compiled
  • TypeScript generation time
  • Bun bundling time

🔧 Common Issues

Runtime.js Not Loading

Symptom: boot() never executes, GET /_equantic/runtime.js returns 404

Solution: Ensure SDK package includes runtime.js and CopyEQuanticRuntime target executes

# Check if runtime exists in SDK package
unzip -l ~/.nuget/packages/equantic.ui.sdk/0.1.1/equantic.ui.sdk.0.1.1.nupkg | grep runtime

# Force rebuild
dotnet clean
dotnet build -v:n  # Check for "Copying runtime.js" message

Theme Classes Missing in CSR

Symptom: Server-rendered HTML has full theme classes, but client-side doesn't

Root Cause: __registerTheme() not called or theme provider not initialized

Solution:

  1. Verify runtime.js loads before component scripts
  2. Check browser console for [eQuantic.UI] Boot process started
  3. Inspect window.__themes in console - should contain theme definitions

Source Maps Not Working

Symptom: Can't debug original C# code in browser DevTools

Solution:

  1. Ensure sourcemap: true in vite.config.ts
  2. Check that .map files exist in wwwroot/_equantic/
  3. Enable source maps in browser DevTools settings
  4. Clear browser cache and rebuild

Error Overlay Not Appearing

Symptom: Errors logged to console but no overlay

Checks:

  1. Is window.__EQ_DEV__ true? (Check in console)
  2. Is error overlay imported? (Check runtime.js includes it)
  3. Is error overlay CSS loaded? (Check for #equantic-error-overlay styles)

Force Show:

// Manually trigger overlay
import { errorOverlay } from "@equantic/ui-runtime/dev";
errorOverlay.show({ message: "Test error" });

🎯 Best Practices

Development Workflow

  1. Use Logger Liberally: Add debug logs during development, they're free in production
  2. Test Both Modes: Always test with Development and Production environment
  3. Monitor Network: Keep DevTools Network tab open to catch failed Server Actions
  4. Enable Source Maps: Always build with source maps in development
  5. Use Error Overlay: Don't suppress errors - let the overlay show them

Production Debugging

For production issues:

  1. Server Logs: Check ASP.NET Core logs for Server Action errors
  2. Browser Console: Only warn and error logs appear
  3. Sentry/AppInsights: Integrate error tracking services
  4. Source Maps: Optionally deploy .map files to separate server for production debugging

Debugging Checklist

Before reporting issues:

  • Check browser console for errors
  • Verify window.__EQ_DEV__ is true (dev) or false (prod)
  • Confirm runtime.js loads (Network tab)
  • Check for theme registration (window.__themes)
  • Test with browser cache disabled
  • Try in incognito/private mode
  • Compare SSR HTML with CSR HTML
  • Check MSBuild output for warnings
  • Verify NuGet packages are correct versions

📚 Related Documentation

Clone this wiki locally