| name | electrobun-debugging |
| description | Development workflow, debugging, and troubleshooting for Electrobun desktop applications. This skill covers debugging the main process (Bun) and webview processes, Chrome DevTools integration, console logging strategies, error handling, performance profiling, memory leak detection, build error troubleshooting, common runtime errors, development environment setup, hot reload configuration, source maps, breakpoint debugging, network inspection, WebView debugging on different platforms, native module debugging, and systematic debugging approaches. Use when encountering build failures, runtime errors, crashes, performance issues, debugging RPC communication, inspecting webview DOM, profiling CPU/memory usage, troubleshooting platform-specific issues, or setting up development workflow. Triggers include "debug", "error", "crash", "troubleshoot", "DevTools", "inspect", "breakpoint", "profiling", "performance issue", "build error", "not working", or "logging". |
| license | MIT |
| metadata | {"author":"Blackboard","version":"1.0.0"} |
Electrobun Debugging
Comprehensive debugging and troubleshooting guide for Electrobun applications.
Development Environment
Basic Development Setup
bun run dev
DEBUG=* bun run dev
DEBUG=electrobun:* bun run dev
Environment Configuration
.env.development:
NODE_ENV=development
DEBUG=electrobun:*
ELECTRON_ENABLE_DEVTOOLS=1
ELECTRON_DISABLE_SECURITY_WARNINGS=true
DEV_SERVER_PORT=3000
Debugging Main Process
Console Logging
console.log("Main process started");
console.error("Error in main process");
console.warn("Warning in main process");
const logger = {
debug: (msg: string, data?: any) => {
if (process.env.DEBUG) {
console.log(`[DEBUG] ${msg}`, data || "");
}
},
info: (msg: string, data?: any) => {
console.log(`[INFO] ${msg}`, data || "");
},
error: (msg: string, error?: any) => {
console.error(`[ERROR] ${msg}`, error || "");
if (error?.stack) {
console.error(error.stack);
}
}
};
logger.info("Window created", { width: 1200, height: 800 });
logger.error("Failed to load file", error);
Bun Debugger
bun --inspect run dev
bun --inspect-brk run dev
Error Handling in Main
process.on("uncaughtException", (error) => {
logger.error("Uncaught exception", error);
dialog.showMessageBox({
type: "error",
title: "Application Error",
message: "An unexpected error occurred",
detail: error.message,
});
});
process.on("unhandledRejection", (reason, promise) => {
logger.error("Unhandled rejection", { reason, promise });
});
win.on("error", (error) => {
logger.error("Window error", error);
});
win.defineRpc({
handlers: {
async someHandler(args: any) {
try {
return { success: true };
} catch (error) {
logger.error("RPC handler error", error);
throw error;
}
}
}
});
Debugging Webview
Chrome DevTools
win.openDevTools();
win.openDevTools({ mode: "detach" });
win.toggleDevTools();
win.closeDevTools();
{
label: "Toggle Developer Tools",
accelerator: "CmdOrCtrl+Shift+I",
action: () => win.toggleDevTools()
}
Console Logging in Webview
console.log("Webview initialized");
console.error("Error in webview");
console.warn("Warning in webview");
console.table({ user: "Alice", age: 30 });
const logger = {
log: (msg: string, ...args: any[]) => {
console.log(`[${new Date().toISOString()}] ${msg}`, ...args);
},
group: (label: string) => {
console.group(label);
},
groupEnd: () => {
console.groupEnd();
}
};
logger.group("User Login");
logger.log("Validating credentials");
logger.log("Fetching user data");
logger.groupEnd();
Capturing Webview Errors
window.addEventListener("error", (event) => {
console.error("Uncaught error:", event.error);
electroview.rpc.logError({
message: event.error.message,
stack: event.error.stack,
url: event.filename,
line: event.lineno,
column: event.colno,
});
});
window.addEventListener("unhandledrejection", (event) => {
console.error("Unhandled rejection:", event.reason);
electroview.rpc.logError({
message: "Unhandled rejection",
reason: event.reason,
});
});
win.defineRpc({
handlers: {
async logError(error: any) {
logger.error("Webview error", error);
await saveErrorLog(error);
}
}
});
Debugging RPC Communication
RPC Logging
class RpcLogger {
wrap(handlers: any) {
const wrapped: any = {};
for (const [name, handler] of Object.entries(handlers)) {
wrapped[name] = async (...args: any[]) => {
const callId = Math.random().toString(36).slice(2);
logger.debug(`[RPC:${callId}] → ${name}`, args);
const startTime = Date.now();
try {
const result = await (handler as Function)(...args);
const duration = Date.now() - startTime;
logger.debug(`[RPC:${callId}] ← ${name} (${duration}ms)`, result);
return result;
} catch (error) {
const duration = Date.now() - startTime;
logger.error(`[RPC:${callId}] ✗ ${name} (${duration}ms)`, error);
throw error;
}
};
}
return wrapped;
}
}
const rpcLogger = new RpcLogger();
win.defineRpc({
handlers: rpcLogger.wrap({
async getUser(id: string) {
return await database.users.findById(id);
},
async saveFile(path: string, content: string) {
await Bun.write(path, content);
return { success: true };
}
})
});
Testing RPC in DevTools
await electroview.rpc.getUser("123")
try {
await electroview.rpc.invalidMethod()
} catch (error) {
console.error("Expected error:", error);
}
console.time("RPC call");
const result = await electroview.rpc.getUser("123");
console.timeEnd("RPC call");
Performance Profiling
CPU Profiling
const { performance, PerformanceObserver } = require("perf_hooks");
const obs = new PerformanceObserver((items) => {
items.getEntries().forEach(entry => {
logger.debug(`${entry.name}: ${entry.duration}ms`);
});
});
obs.observe({ entryTypes: ["measure"] });
performance.mark("operation-start");
await expensiveOperation();
performance.mark("operation-end");
performance.measure("operation", "operation-start", "operation-end");
Webview CPU profiling:
console.profile("My Operation");
await performOperation();
console.profileEnd("My Operation");
const start = performance.now();
await operation();
const duration = performance.now() - start;
console.log(`Operation took ${duration}ms`);
Memory Profiling
function logMemoryUsage() {
const usage = process.memoryUsage();
logger.info("Memory usage", {
heapUsed: `${Math.round(usage.heapUsed / 1024 / 1024)}MB`,
heapTotal: `${Math.round(usage.heapTotal / 1024 / 1024)}MB`,
external: `${Math.round(usage.external / 1024 / 1024)}MB`,
rss: `${Math.round(usage.rss / 1024 / 1024)}MB`,
});
}
setInterval(logMemoryUsage, 10000);
if (global.gc) {
global.gc();
logMemoryUsage();
}
Webview memory profiling:
if (performance.memory) {
console.log("Memory:", {
used: `${Math.round(performance.memory.usedJSHeapSize / 1024 / 1024)}MB`,
total: `${Math.round(performance.memory.totalJSHeapSize / 1024 / 1024)}MB`,
limit: `${Math.round(performance.memory.jsHeapSizeLimit / 1024 / 1024)}MB`,
});
}
Common Issues & Solutions
Build Errors
Issue: "Cannot find module 'electrobun'"
bun install
bun pm ls electrobun
Issue: Native module compilation fails
xcode-select --install
sudo apt install build-essential
Issue: "WebView2 not found" (Windows)
Runtime Errors
Issue: Window not showing
console.log("Window created:", win);
win.show();
console.log("Window bounds:", win.getBounds());
console.log("Window visible:", win.isVisible());
console.log("Window minimized:", win.isMinimized());
Issue: RPC not working
console.log("RPC handlers:", Object.keys(handlers));
win.on("did-finish-load", () => {
console.log("Webview loaded");
});
try {
const result = await electroview.rpc.testMethod();
console.log("RPC working:", result);
} catch (error) {
console.error("RPC error:", error);
}
Issue: High memory usage
window.removeEventListener("resize", handler);
win.on("close", () => {
clearInterval(intervalId);
ws.close();
cache.clear();
});
Platform-Specific Issues
macOS:
<key>NSCameraUsageDescription</key>
<string>App needs camera access</string>
<key>NSMicrophoneUsageDescription</key>
<string>App needs microphone access</string>
Windows:
Linux:
sudo apt install libwebkit2gtk-4.1-dev
ldd dist/MyApp
Debugging Tools
Network Inspection
win.on("will-navigate", (event) => {
logger.debug("Navigating to:", event.url);
if (event.url.includes("blocked.com")) {
event.preventDefault();
}
});
win.webContents.session.webRequest.onBeforeRequest((details, callback) => {
logger.debug("Request:", details.url);
callback({});
});
Source Maps
Ensure source maps are enabled for better debugging:
{
"compilerOptions": {
"sourceMap": true,
"inlineSourceMap": false,
"inlineSources": true
}
}
Systematic Debugging Approach
async function debugIssue() {
logger.info("=== Debug Session Started ===");
logger.info("Environment:", {
platform: process.platform,
version: app.getVersion(),
development: process.env.NODE_ENV === "development",
});
try {
logger.info("Step 1: Initialize");
logger.info("Step 2: Execute");
logger.info("Step 3: Verify");
logger.info("=== Debug Session Complete ===");
} catch (error) {
logger.error("=== Debug Session Failed ===", error);
throw error;
}
}
Resources
For more on Electrobun: