penpot/.serena/memories/frontend/handling-errors-and-debugging.md
Michael Panchenko 7a2ca6c08f 🎉 Add two new MCP tools for Clojure development
* CljsCompilerOutputTool: Checks compiler output and reports errors
* CljCheckParentheses: Precisely locates incorrect/unbalanced parentheses

GitHub #9214
2026-05-12 12:49:58 +02:00

2.1 KiB

Handling Errors and Debugging

Finding source errors

You have access to two tools for finding errors in Clojure source code (which you may introduce yourself through edits):

  1. cljs_compiler_output
  2. clj_check_parentheses

The latter is needed because syntax errors in parentheses give an uninformative compiler error, and the second tool can often find the exact location of such errors.

Runtime patching with set!

Some frontend vars are deliberately mutable escape hatches for runtime instrumentation or circular-dependency patching. From cljs_repl, use set! for temporary debugging of CLJS vars such as app.main.store/on-event, app.main.errors/reload-file, app.main.errors/is-plugin-error?, app.main.errors/last-report, or app.main.errors/last-exception. These patches affect only the live browser runtime and disappear on reload or recompilation.

;; Log non-noisy Potok events temporarily.
(set! app.main.store/on-event
      (fn [event]
        (when (potok.v2.core/event? event)
          (.log js/console (potok.v2.core/repr-event event)))))

Restore mutable hooks after debugging, or reload the frontend. Use JVM alter-var-root only for JVM Clojure; it is not the normal way to patch live CLJS browser vars.

Browser-console debug namespace

In development, the JS console exposes debug helpers from frontend/src/debug.cljs:

debug.set_logging("namespace", "debug");
debug.dump_state();
debug.dump_buffer();
debug.get_state(":workspace-local :selected");
debug.dump_objects();
debug.dump_object("Rect-1");
debug.dump_selected();
debug.dump_tree(true, true);

Visual workspace debug overlays can be toggled with debug.toggle_debug("bounding-boxes"), "group", "events", or "rotation-handler"; debug.debug_all() and debug.debug_none() toggle all visual aids.

For temporary source traces, prefer existing logging (app.common.logging / app.util.logging) or short-lived prn, app.common.pprint/pprint, js/console.log, or js-debugger calls. Remove temporary source instrumentation before committing.