Debugging Strategies and Tools for Developers Working with the Read Frog Extension

The most effective debugging strategies for Read Frog developers include using the centralized logger utility in src/utils/logger.ts, monitoring the request queue's task lifecycle in src/utils/request/request-queue.ts, simulating four-finger gestures with scripts/debug/four-finger-touch.js, and leveraging Chrome DevTools with source maps for TypeScript debugging.

Read Frog is a modern browser extension built with TypeScript, React 19, and Manifest V3 that helps users translate and process web content. Because it operates across content scripts, background service workers, and popup contexts, developers need specific debugging strategies and tools to trace issues through these isolated execution environments. This guide covers the essential debugging utilities and workflows built into the Read Frog codebase.

Centralized Logging with the Logger Utility

The project ships a tiny wrapper around console that adds colour, prefixes and automatic source-location hints. It is defined in src/utils/logger.ts. All internal modules import createLogger and use the returned methods (log, info, warn, error).

How createLogger Works

The logger factory accepts a namespace string and returns an object with methods that prepend coloured labels to console output. For example, the request queue logs task lifecycle events (see lines 44-69 and 126-151 in src/utils/request/request-queue.ts).

// src/utils/logger.ts – create a logger for the request queue
import { createLogger } from '@/utils/logger';

const log = createLogger('RequestQueue');

/* Inside src/utils/request/request-queue.ts */
log.info(`✅ Task ${task.id} added to queue. Queue size: ${this.waitingQueue.size()}`);
log.warn(`⏰ Task ${task.id} timed out after ${this.options.timeoutMs}ms`);
log.error(`❌ Task ${task.id} failed permanently after ${this.options.maxRetries} retries`);

Filtering Logs in DevTools

Consistent formatting makes it easy to filter messages in Chrome DevTools. The colour prefix (%c) highlights the extension’s own logs among other page scripts. By centralising the logger you can swap it out for a more sophisticated solution (e.g., sending logs to a remote server) without touching every module.

Debugging Network Requests with the Request Queue

All outbound AI and translation calls go through src/utils/request/request-queue.ts. The queue implements retries, time-outs and token-bucket rate limiting, and it emits verbose logs at each stage (task addition, execution start, timeout, retry, permanent failure).

When a request misbehaves, the logs show the task ID, retry count, and timestamps, which are invaluable for reproducing flaky network issues. Developers can trace a failed translation request from the UI component through to the queue and identify whether the failure stems from network timeouts, rate limiting, or API errors.

Simulating User Interactions for UI Debugging

Four-Finger Touch Gesture Simulation

During UI development the team uses a small helper script located at scripts/debug/four-finger-touch.js. Running this script injects a button into any page that, when clicked, simulates a four-finger tap event – the gesture Read Frog uses to open its popup. The script also prints step-by-step status messages (see lines 4-92).

// scripts/debug/four-finger-touch.js
function simulateFourFingerTap() {
  console.log('🐸 Read Frog - 四手指触摸调试脚本');
  // … create TouchEvent with 4 touch points …
  document.dispatchEvent(touchStartEvent);
  document.dispatchEvent(touchEndEvent);
}

// Add a button to the page for quick testing
function addDebugButton() {
  const btn = document.createElement('button');
  btn.textContent = '🔧 Read Frog Debug';
  btn.style.position = 'fixed';
  btn.style.top = '8px';
  btn.style.right = '8px';
  btn.onclick = simulateFourFingerTap;
  document.body.appendChild(btn);
}

addDebugButton();

Typical workflow:


# From the repo root

node scripts/debug/four-finger-touch.js

Open the target page, click the injected “Debug” button, and watch the console output to verify that the content-script correctly receives the gesture.

Testing and Error Handling Strategies

Unit Testing with Vitest

The repository includes a full Vitest setup (vitest.config.ts, vitest.setup.ts). Test files live alongside the source (*.test.tsx, *.test.ts). Running pnpm test executes them in a headless JSDOM environment, catching logical errors before they reach the browser.

Tip: Add console.log statements or use the logger inside tests to surface intermediate values when a test fails.

Runtime Error Handling in Components

Most async entry points wrap operations in try … catch blocks and log errors via the logger. For example, translation button errors in src/entrypoints/selection.content/selection-toolbar/translate-button.tsx (line 147) follow this pattern:

// src/entrypoints/selection.content/selection-toolbar/translate-button.tsx
async function handleTranslate() {
  try {
    await translateSelection(); // goes through request‑queue
  } catch (error) {
    // Unified error logging
    console.error('Translation error:', error);
  }
}

When translateSelection throws, the catch block prints the error; you can then follow the task ID from the request-queue logs to locate the root cause. Similarly, configuration migration errors in src/utils/config/init.ts use console.error statements to surface initialization failures.

Browser DevTools and Extension Debugging

Because the extension’s code is bundled with Vite, source maps are generated automatically. Open chrome://extensions → “Inspect views” for the background/service worker, or right-click a page and choose “Inspect” to debug the content script.

  • Set breakpoints directly in the compiled sources; the source maps will map them back to the original TypeScript files (e.g., src/entrypoints/translation-hub/...).
  • Use the “Console” tab filtered by loglevel:info to focus on Read Frog’s prefixed logs.

State in the extension is handled by Jotai. The Jotai DevTools extension (if installed) shows the atom graph and current values, allowing you to verify that configuration or UI state updates as expected.

Summary

  • Use the centralized logger in src/utils/logger.ts to generate colour-coded, namespaced console output that makes filtering in DevTools trivial.
  • Monitor the request queue in src/utils/request/request-queue.ts to trace network failures, retries, and timeouts via task ID logging.
  • Simulate gestures with scripts/debug/four-finger-touch.js to test the four-finger tap interaction without needing a touch device.
  • Run Vitest (pnpm test) to catch logic errors early in a headless environment before deploying to the browser.
  • Leverage Chrome DevTools with source maps to debug TypeScript directly in content scripts and service workers.

Frequently Asked Questions

How do I filter Read Frog logs in Chrome DevTools?

Open the Console panel in Chrome DevTools and type -RequestQueue or the specific namespace used in createLogger to filter messages. Because the logger uses %c colour prefixes, you can also filter by log level (info, warn, error) to isolate specific severity levels. The consistent formatting makes it easy to distinguish Read Frog’s output from other page scripts.

What is the best way to debug network timeouts in the request queue?

When a network request fails in src/utils/request/request-queue.ts, the logger emits messages containing the task ID, retry count, and timestamp. Search the console for the task ID associated with your failed request to see the full lifecycle—from addition to the queue through each retry attempt to final failure. This traceability allows you to distinguish between actual network timeouts, rate limiting, or API errors.

How can I test the four-finger gesture without a touch device?

Run the Node.js script located at scripts/debug/four-finger-touch.js from the repository root using node scripts/debug/four-finger-touch.js. This injects a floating "Debug" button into the current page that simulates a four-finger tap event when clicked, triggering the same content-script handlers that would fire on an actual touch device. The script also prints step-by-step status messages to the console to verify the gesture flow.

Where should I add error handling for new content script features?

Wrap async operations in try … catch blocks and use the centralized logger from src/utils/logger.ts rather than raw console statements. For UI components, follow the pattern in src/entrypoints/selection.content/selection-toolbar/translate-button.tsx (line 147), where errors are caught and logged with context. For initialization logic, refer to src/utils/config/init.ts for migration error handling patterns. This ensures errors are visible in DevTools and traceable through the logger’s namespace prefixes.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →