How Debug Logs and Troubleshooting Work in Markdown Here: A Complete Guide

Debug logs in Markdown Here are controlled by a module-level DEBUG flag in src/common/common-logic.js, which when enabled formats and routes diagnostic strings through Utils.consoleLog() to the browser console, while an extensible mylog placeholder and safety wrappers provide additional troubleshooting flexibility across Chrome, Firefox, and Thunderbird.

Markdown Here is a browser extension and email client add-on that converts Markdown to rich text. Understanding its debug logs and troubleshooting mechanisms is essential for developers maintaining the codebase or diagnosing cross-platform rendering issues.

Debug Log Generation Mechanism

The logging system follows a deliberate five-step pipeline to minimize overhead in production while providing detailed traces during development.

The DEBUG Flag and Gatekeeping

At the heart of the system is a module-level constant defined in src/common/common-logic.js:

var DEBUG = false;

This Boolean acts as a global switch. All diagnostic functions check this flag before performing any work. When DEBUG is false, the application avoids the overhead of string concatenation and console I/O entirely.

Building and Forwarding Log Messages

The debugLog() function in src/common/common-logic.js handles message construction. It accepts variadic arguments and joins them with a // delimiter:

function debugLog() {
  if (!DEBUG) { return; }
  
  var log = '';
  for (var i = 0; i < arguments.length; i++) {
    log += String(arguments[i]) + ' // ';
  }
  
  Utils.consoleLog(log);
}

This formatting makes multi-part trace statements readable at a glance. For example, calling debugLog('forgotToRenderIntervalCheck', 'pref disabled') produces the output forgotToRenderIntervalCheck // pref disabled //.

Safe Console Output via Utils

All log output funnels through Utils.consoleLog() in src/common/utils.js, which provides environment safety:

function consoleLog(logString) {
  if (typeof(console) !== 'undefined') {
    console.log(logString);
  }
}

This wrapper ensures the extension does not throw reference errors in restricted contexts where console might be undefined, such as certain Thunderbird sandboxes or content security policy-restricted pages.

Extending Troubleshooting Capabilities

Beyond the basic DEBUG system, Markdown Here provides several specialized mechanisms for different troubleshooting scenarios.

External Logger Integration (mylog)

For production diagnostics or Firefox-specific deployments, the code includes a stub function in src/common/markdown-here.js:

var mylog = function() {};

This intentionally empty function serves as an injection point. Developers can replace this stub with a remote logging implementation to capture diagnostic data from end users without requiring browser console access:

var mylog = function(message) {
  fetch('https://log.myapp.example/collect', {
    method: 'POST',
    body: JSON.stringify({msg: message, timestamp: Date.now()}),
    headers: {'Content-Type': 'application/json'}
  });
};

Test Suite Debugging

The Mocha test runner in src/common/test/mocha.js utilizes the debug npm module for detailed test-time tracing:

var debug = require('browser/debug');
// Later usage:
debug('timeout %d', ms);

This provides granular visibility into asynchronous test execution without cluttering the production build.

Permanent Error Messages

Certain critical failure paths bypass the DEBUG gate entirely to surface urgent issues. In src/common/common-logic.js, hard failures such as missing DOM elements trigger unconditional logs:

Utils.consoleLog('Markdown Here was unable to find the Gmail "Send" button…');

These messages appear regardless of the debug flag state, ensuring users and developers immediately see configuration errors or breaking changes in email client DOM structures.

Practical Debugging Examples

To enable comprehensive tracing during development, modify src/common/common-logic.js:

var DEBUG = true;

With this enabled, internal functions like forgotToRenderIntervalCheck emit detailed traces:

function forgotToRenderIntervalCheck(focusedElem, MarkdownHere, MdhHtmlToText, marked, prefs) {
  if (!prefs['forgot-to-render-check-enabled-2']) {
    debugLog('forgotToRenderIntervalCheck', 'pref disabled');
    return;
  }
  debugLog('forgotToRenderIntervalCheck', 'starting check', focusedElem.tagName);
  // ... logic continues
}

Console output with DEBUG = true:


forgotToRenderIntervalCheck // pref disabled //

To capture logs from users experiencing issues in Firefox, combine the mylog replacement with the existing debugLog calls. Since debugLog routes through the console by default, you may also patch Utils.consoleLog to dual-write to both the console and your remote endpoint:

var originalConsoleLog = Utils.consoleLog;
Utils.consoleLog = function(logString) {
  originalConsoleLog(logString); // Keep browser console output
  mylog(logString);              // Send to external service
};

Summary

  • The DEBUG flag in src/common/common-logic.js acts as a master switch; set it to true to enable all diagnostic output.
  • The debugLog() function formats messages with // separators and forwards them to Utils.consoleLog().
  • The Utils.consoleLog() wrapper in src/common/utils.js safely calls console.log only when the environment supports it.
  • The mylog placeholder in src/common/markdown-here.js allows injection of remote logging for Firefox or production diagnostics.
  • Permanent error messages bypass the debug flag to report critical failures like missing DOM elements immediately.

Frequently Asked Questions

How do I enable debug logs in Markdown Here?

Set var DEBUG = true; in src/common/common-logic.js. This activates the debugLog() function throughout the codebase. You must reload the extension for the change to take effect in Chrome, or restart Thunderbird/Firefox depending on your installation method.

Where are debug logs output when enabled?

Logs route to the browser's native console via Utils.consoleLog() in src/common/utils.js. The wrapper checks typeof(console) !== 'undefined' before writing, preventing errors in restricted environments. No log files are created on disk; output appears in the Developer Tools console or Error Console depending on the platform.

Can I send logs to an external server instead of the console?

Yes. Replace the empty mylog function in src/common/markdown-here.js with your own implementation that POSTs data to your endpoint. While debugLog itself does not call mylog directly, you can override Utils.consoleLog to call both the native console and your mylog implementation for comprehensive remote monitoring.

What's the difference between debugLog and Utils.consoleLog?

debugLog() is a developer-facing function in common-logic.js that builds formatted strings and checks the DEBUG flag before doing any work. Utils.consoleLog() is a low-level utility in utils.js that performs the actual environment-safe console write. All debug output flows through both functions, while critical error messages may call Utils.consoleLog directly to bypass the debug flag check.

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 →