Error Handling Strategy for Uncaught Exceptions and Unhandled Promise Rejections in DesktopCommanderMCP

DesktopCommanderMCP implements a centralized fail-fast strategy that captures fatal errors through global process listeners, logs structured telemetry, and immediately terminates the process with exit code 1 to prevent undefined behavior, with special carve-outs for recoverable JSON parsing errors.

DesktopCommanderMCP centralizes its runtime error handling in src/index.ts to ensure predictable failure modes in long-running server processes. The application registers global process listeners immediately after transport creation, intercepting uncaught exceptions and unhandled promise rejections before they can corrupt application state. This error handling strategy for uncaught exceptions and unhandled promise rejections prioritizes observability and rapid recovery over attempting to continue execution in an compromised state.

Global Error Listener Registration

The server binds two critical event listeners in src/index.ts during initialization. These handlers are positioned early in the lifecycle (lines 78–110) to guarantee capture of all runtime errors.

Uncaught Exception Handling

The uncaughtException listener (lines 78–93 of src/index.ts) intercepts any synchronous error that bubbles outside the event loop. When triggered, the handler extracts the error message, emits a log entry via logger.error(), and records a telemetry event using the capture() utility from src/utils/capture.ts.

By default, the process immediately terminates with process.exit(1) to avoid undefined behavior. However, if the error message contains both "JSON" and "Unexpected token", the handler logs the incident but does not exit, allowing the server to continue operating despite the parsing failure.

Unhandled Promise Rejection Handling

The unhandledRejection listener (lines 96–110 of src/index.ts) follows an identical pattern for asynchronous promise rejections that lack a .catch() handler. The handler extracts the rejection reason, logs the error through the central logger, fires a capture('run_server_unhandled_rejection', …) event, and terminates the process with status code 1.

Like its synchronous counterpart, this handler exempts JSON parsing errors from termination, simply logging them and allowing execution to continue.

Telemetry Integration and Observability

Both error handlers utilize the capture utility exported from src/utils/capture.ts to transmit structured telemetry events to the monitoring pipeline. This ensures that every fatal error is observable post-mortem, even after the process exits. The telemetry events—run_server_uncaught_exception and run_server_unhandled_rejection—include error metadata that facilitates rapid debugging and incident response.

The centralized logging facade in src/utils/logger.ts provides consistent formatting across all error outputs, ensuring that log entries contain sufficient context for tracing failures back to their origin.

The Fail-Fast Philosophy with JSON Exceptions

DesktopCommanderMCP adheres to the fail-fast principle: encountering an unrecoverable error state triggers immediate termination rather than risking silent corruption or resource leaks. This approach is essential for MCP (Model Context Protocol) servers that must maintain consistent state across tool executions.

The deliberate exception for JSON parsing errors reflects a pragmatic concession to common serialization edge cases. When these specific errors occur, the server assumes the transport or client sent malformed data that does not compromise the server's internal state, allowing the process to continue serving subsequent requests.

Practical Code Examples

The following snippets demonstrate how the global handlers intercept fatal errors:

// Simulates an uncaught exception that triggers process.exit(1)
setTimeout(() => {
  throw new Error('Simulated fatal error');
}, 1000);
// Simulates an unhandled promise rejection
// Note: Missing .catch() causes the unhandledRejection event
Promise.reject(new Error('Simulated rejection'));

Executing either snippet results in:

  • A log entry formatted as Uncaught exception: Simulated fatal error or Unhandled rejection: Simulated rejection
  • A telemetry capture event sent via capture()
  • Process termination with exit code 1 (unless the error matches the JSON parsing pattern)

Summary

  • DesktopCommanderMCP registers global error listeners in src/index.ts immediately after server startup to capture all uncaught exceptions and unhandled promise rejections.
  • The fail-fast strategy terminates the process with process.exit(1) after logging and capturing telemetry, preventing undefined behavior in long-running processes.
  • JSON parsing errors ("JSON" + "Unexpected token") are treated as recoverable exceptions that log but do not trigger termination.
  • The capture utility in src/utils/capture.ts sends structured telemetry for post-mortem analysis.
  • This centralized approach ensures that the server never persists in a corrupted state, instead forcing a clean restart via the supervising process.

Frequently Asked Questions

What happens when an uncaught exception occurs in DesktopCommanderMCP?

The server invokes the handler in src/index.ts (lines 78–93), which logs the error via logger.error(), records a run_server_uncaught_exception telemetry event through capture(), and terminates the process with exit code 1. The only exception is JSON parsing errors, which are logged but allow the process to continue.

Why does DesktopCommanderMCP exit on unhandled promise rejections?

Unhandled promise rejections indicate that an asynchronous operation failed without error handling, leaving the application in an undefined state. According to the source code in lines 96–110 of src/index.ts, the server exits immediately to prevent resource leaks and inconsistent behavior, following the Node.js best practice of treating unhandled rejections as fatal.

Are there any errors that do not trigger process termination?

Yes. If an uncaught exception or unhandled rejection contains the strings "JSON" and "Unexpected token", the handler recognizes it as a parsing error. In this specific case, the error is logged but process.exit(1) is not called, allowing the server to recover from malformed JSON input without restarting.

Where is the error handling logic implemented?

The primary implementation resides in src/index.ts, specifically lines 78–93 for uncaughtException and lines 96–110 for unhandledRejection. Supporting utilities are located in src/utils/logger.ts for logging and src/utils/capture.ts for telemetry transmission.

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 →