Skip to content

cider-stacktrace-render works incorrectly for ClojureScript #3821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
rrudakov opened this issue May 17, 2025 · 1 comment
Open

cider-stacktrace-render works incorrectly for ClojureScript #3821

rrudakov opened this issue May 17, 2025 · 1 comment
Labels

Comments

@rrudakov
Copy link
Contributor

Expected behavior

When I eval a ClojureScript expression that causes an exception, *cider-error* buffer is displayed with the exception data.

Actual behavior

The *cider-error* buffer contains only the following text:


  Show: Project-Only All 
  Hide: Clojure Java REPL Tooling Duplicates  (0 frames hidden)

and the following error is signaled:

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  propertize(nil font-lock-face cider-stacktrace-error-class-face mouse-face highlight)
  (insert (format "%d. " num) (propertize note 'font-lock-face 'font-lock-comment-face) " " (propertize class 'font-lock-face class-face 'mouse-face 'highlight) "\n")
  (progn (insert (format "%d. " num) (propertize note 'font-lock-face 'font-lock-comment-face) " " (propertize class 'font-lock-face class-face 'mouse-face 'highlight) "\n"))
  (prog1 (progn (insert (format "%d. " num) (propertize note 'font-lock-face 'font-lock-comment-face) " " (propertize class 'font-lock-face class-face 'mouse-face 'highlight) "\n")) (add-text-properties start (point) (list 'detail 0 'inspect-index inspect-index 'keymap cider-stacktrace-exception-map)))
  (let ((start (point))) (prog1 (progn (insert (format "%d. " num) (propertize note 'font-lock-face 'font-lock-comment-face) " " (propertize class 'font-lock-face class-face 'mouse-face 'highlight) "\n")) (add-text-properties start (point) (list 'detail 0 'inspect-index inspect-index 'keymap cider-stacktrace-exception-map))))
  (progn (let ((start (point))) (prog1 (progn (insert (format "%d. " num) (propertize note 'font-lock-face 'font-lock-comment-face) " " (propertize class 'font-lock-face class-face 'mouse-face 'highlight) "\n")) (add-text-properties start (point) (list 'detail 0 'inspect-index inspect-index 'keymap cider-stacktrace-exception-map)))) (let ((start (point))) (prog1 (progn (if (equal class "clojure.lang.Compiler$CompilerException") (cider-stacktrace-render-compile-error buffer cause) (cider-stacktrace-emit-indented (propertize (or message "(No message)") 'font-lock-face message-face) indent t)) (if triage (progn (insert "\n") (cider-stacktrace-emit-indented (propertize ... ... message-face) indent nil))) (if spec (progn (insert "\n") (cider-stacktrace--emit-spec-problems spec (concat indent "  ")))) (if data (progn (insert "\n") (let (...) (prog1 ... ...)))) (insert "\n")) (add-text-properties start (point) '(detail 1)))) (let ((start (point))) (prog1 (progn (let ((beg (point)) (bg (cons ... ...))) (let ((tail stacktrace)) (while tail (let ... ... ... ...))) (overlay-put (make-overlay beg (point)) 'font-lock-face bg))) (add-text-properties start (point) '(detail 2)))) (let ((start (point))) (prog1 (progn (insert "\n")) (add-text-properties start (point) '(detail 0)))))
  (prog1 (progn (let ((start (point))) (prog1 (progn (insert (format "%d. " num) (propertize note 'font-lock-face 'font-lock-comment-face) " " (propertize class 'font-lock-face class-face 'mouse-face 'highlight) "\n")) (add-text-properties start (point) (list 'detail 0 'inspect-index inspect-index 'keymap cider-stacktrace-exception-map)))) (let ((start (point))) (prog1 (progn (if (equal class "clojure.lang.Compiler$CompilerException") (cider-stacktrace-render-compile-error buffer cause) (cider-stacktrace-emit-indented (propertize ... ... message-face) indent t)) (if triage (progn (insert "\n") (cider-stacktrace-emit-indented ... indent nil))) (if spec (progn (insert "\n") (cider-stacktrace--emit-spec-problems spec ...))) (if data (progn (insert "\n") (let ... ...))) (insert "\n")) (add-text-properties start (point) '(detail 1)))) (let ((start (point))) (prog1 (progn (let ((beg ...) (bg ...)) (let (...) (while tail ...)) (overlay-put (make-overlay beg ...) 'font-lock-face bg))) (add-text-properties start (point) '(detail 2)))) (let ((start (point))) (prog1 (progn (insert "\n")) (add-text-properties start (point) '(detail 0))))) (add-text-properties start (point) (list 'cause num)))
  (let ((start (point))) (prog1 (progn (let ((start (point))) (prog1 (progn (insert (format "%d. " num) (propertize note ... ...) " " (propertize class ... class-face ... ...) "\n")) (add-text-properties start (point) (list 'detail 0 'inspect-index inspect-index 'keymap cider-stacktrace-exception-map)))) (let ((start (point))) (prog1 (progn (if (equal class "clojure.lang.Compiler$CompilerException") (cider-stacktrace-render-compile-error buffer cause) (cider-stacktrace-emit-indented ... indent t)) (if triage (progn ... ...)) (if spec (progn ... ...)) (if data (progn ... ...)) (insert "\n")) (add-text-properties start (point) '(detail 1)))) (let ((start (point))) (prog1 (progn (let (... ...) (let ... ...) (overlay-put ... ... bg))) (add-text-properties start (point) '(detail 2)))) (let ((start (point))) (prog1 (progn (insert "\n")) (add-text-properties start (point) '(detail 0))))) (add-text-properties start (point) (list 'cause num))))
  (let ((indent "   ") (class-face 'cider-stacktrace-error-class-face) (message-face 'cider-stacktrace-error-message-face)) (let ((start (point))) (prog1 (progn (let ((start (point))) (prog1 (progn (insert ... ... " " ... "\n")) (add-text-properties start (point) (list ... 0 ... inspect-index ... cider-stacktrace-exception-map)))) (let ((start (point))) (prog1 (progn (if ... ... ...) (if triage ...) (if spec ...) (if data ...) (insert "\n")) (add-text-properties start (point) '...))) (let ((start (point))) (prog1 (progn (let ... ... ...)) (add-text-properties start (point) '...))) (let ((start (point))) (prog1 (progn (insert "\n")) (add-text-properties start (point) '...)))) (add-text-properties start (point) (list 'cause num)))))
  (let ((class (nrepl-dict-get cause "class")) (message (nrepl-dict-get cause "message")) (data (nrepl-dict-get cause "data")) (spec (nrepl-dict-get cause "spec")) (triage (nrepl-dict-get cause "triage")) (stacktrace (nrepl-dict-get cause "stacktrace"))) (let ((indent "   ") (class-face 'cider-stacktrace-error-class-face) (message-face 'cider-stacktrace-error-message-face)) (let ((start (point))) (prog1 (progn (let ((start ...)) (prog1 (progn ...) (add-text-properties start ... ...))) (let ((start ...)) (prog1 (progn ... ... ... ... ...) (add-text-properties start ... ...))) (let ((start ...)) (prog1 (progn ...) (add-text-properties start ... ...))) (let ((start ...)) (prog1 (progn ...) (add-text-properties start ... ...)))) (add-text-properties start (point) (list 'cause num))))))
  (save-current-buffer (set-buffer buffer) (let ((class (nrepl-dict-get cause "class")) (message (nrepl-dict-get cause "message")) (data (nrepl-dict-get cause "data")) (spec (nrepl-dict-get cause "spec")) (triage (nrepl-dict-get cause "triage")) (stacktrace (nrepl-dict-get cause "stacktrace"))) (let ((indent "   ") (class-face 'cider-stacktrace-error-class-face) (message-face 'cider-stacktrace-error-message-face)) (let ((start (point))) (prog1 (progn (let (...) (prog1 ... ...)) (let (...) (prog1 ... ...)) (let (...) (prog1 ... ...)) (let (...) (prog1 ... ...))) (add-text-properties start (point) (list 'cause num)))))))
  cider-stacktrace-render-cause(#<buffer *cider-error*> (dict "id" "134" "session" "4a471f61-529b-4398-aa85-59891c1c8fde" "status" ("no-error")) 1 "Unhandled" 0)
  (let ((note (if (= num causes-length) "Unhandled" "Caused by"))) (cider-stacktrace-render-cause buffer cause num note (- causes-length num)) (setq num (1- num)))
  (let ((cause (car tail))) (let ((note (if (= num causes-length) "Unhandled" "Caused by"))) (cider-stacktrace-render-cause buffer cause num note (- causes-length num)) (setq num (1- num))) (setq tail (cdr tail)))
  (while tail (let ((cause (car tail))) (let ((note (if (= num causes-length) "Unhandled" "Caused by"))) (cider-stacktrace-render-cause buffer cause num note (- causes-length num)) (setq num (1- num))) (setq tail (cdr tail))))
  (let ((tail causes)) (while tail (let ((cause (car tail))) (let ((note (if (= num causes-length) "Unhandled" "Caused by"))) (cider-stacktrace-render-cause buffer cause num note (- causes-length num)) (setq num (1- num))) (setq tail (cdr tail)))))
  (let* ((causes-length (length causes)) (num causes-length)) (let ((tail causes)) (while tail (let ((cause (car tail))) (let ((note (if ... "Unhandled" "Caused by"))) (cider-stacktrace-render-cause buffer cause num note (- causes-length num)) (setq num (1- num))) (setq tail (cdr tail))))))
  (let ((inhibit-read-only t)) (erase-buffer) (insert "\n") (cider-stacktrace-render-filters buffer '(("Project-Only" project) ("All" all)) '(("Clojure" clj) ("Java" java) ("REPL" repl) ("Tooling" tooling) ("Duplicates" dup))) (insert "\n") (if error-types (progn (cider-stacktrace-render-suppression-toggle buffer error-types) (insert "\n\n"))) (let* ((causes-length (length causes)) (num causes-length)) (let ((tail causes)) (while tail (let ((cause (car tail))) (let ((note ...)) (cider-stacktrace-render-cause buffer cause num note (- causes-length num)) (setq num (1- num))) (setq tail (cdr tail)))))))
  (save-current-buffer (set-buffer buffer) (let ((inhibit-read-only t)) (erase-buffer) (insert "\n") (cider-stacktrace-render-filters buffer '(("Project-Only" project) ("All" all)) '(("Clojure" clj) ("Java" java) ("REPL" repl) ("Tooling" tooling) ("Duplicates" dup))) (insert "\n") (if error-types (progn (cider-stacktrace-render-suppression-toggle buffer error-types) (insert "\n\n"))) (let* ((causes-length (length causes)) (num causes-length)) (let ((tail causes)) (while tail (let ((cause ...)) (let (...) (cider-stacktrace-render-cause buffer cause num note ...) (setq num ...)) (setq tail (cdr tail))))))) (cider-stacktrace-initialize causes) (font-lock-refresh-defaults))
  cider-stacktrace-render(#<buffer *cider-error*> ((dict "id" "134" "session" "4a471f61-529b-4398-aa85-59891c1c8fde" "status" ("no-error"))) nil)
  (let* ((repl (or repl (cider-current-repl))) (error-buffer (cider-new-error-buffer #'cider-stacktrace-mode error-types is-compilation))) (save-current-buffer (set-buffer error-buffer) (setq cider--ancillary-buffer-repl repl)) (cider-stacktrace-render error-buffer causes error-types))
  (progn (let* ((repl (or repl (cider-current-repl))) (error-buffer (cider-new-error-buffer #'cider-stacktrace-mode error-types is-compilation))) (save-current-buffer (set-buffer error-buffer) (setq cider--ancillary-buffer-repl repl)) (cider-stacktrace-render error-buffer causes error-types)))
  (if causes (progn (let* ((repl (or repl (cider-current-repl))) (error-buffer (cider-new-error-buffer #'cider-stacktrace-mode error-types is-compilation))) (save-current-buffer (set-buffer error-buffer) (setq cider--ancillary-buffer-repl repl)) (cider-stacktrace-render error-buffer causes error-types))))
  cider--render-stacktrace-causes(((dict "id" "134" "session" "4a471f61-529b-4398-aa85-59891c1c8fde" "status" ("no-error"))) nil nil #<buffer *cider-repl Projects/cljs-tutorial:localhost:61718(cljs:browser)*>)
  cider--handle-stacktrace-response(((dict "id" "134" "session" "4a471f61-529b-4398-aa85-59891c1c8fde" "status" ("no-error"))) nil #<buffer *cider-repl Projects/cljs-tutorial:localhost:61718(cljs:browser)*>)
  #f(lambda (causes phase) [(buffer #<buffer *cider-repl Projects/cljs-tutorial:localhost:61718(cljs:browser)*>)] (cider--handle-stacktrace-response causes phase buffer))(((dict "id" "134" "session" "4a471f61-529b-4398-aa85-59891c1c8fde" "status" ("no-error"))) nil)
  funcall(#f(lambda (causes phase) [(buffer #<buffer *cider-repl Projects/cljs-tutorial:localhost:61718(cljs:browser)*>)] (cider--handle-stacktrace-response causes phase buffer)) ((dict "id" "134" "session" "4a471f61-529b-4398-aa85-59891c1c8fde" "status" ("no-error"))) nil)
  (if (member "done" status) (funcall callback causes ex-phase) (if phase (progn (setq ex-phase phase))) (setq causes (append causes (list response))))
  (let ((status (nrepl-dict-get response "status")) (phase (nrepl-dict-get response "phase"))) (if (member "done" status) (funcall callback causes ex-phase) (if phase (progn (setq ex-phase phase))) (setq causes (append causes (list response)))))
  #f(lambda (response) [(ex-phase nil) (causes ((dict "id" "134" "session" "4a471f61-529b-4398-aa85-59891c1c8fde" "status" ("no-error")))) (callback #f(lambda (causes phase) [(buffer #<buffer *cider-repl Projects/cljs-tutorial:localhost:61718(cljs:browser)*>)] (cider--handle-stacktrace-response causes phase buffer)))] (let ((status (nrepl-dict-get response "status")) (phase (nrepl-dict-get response "phase"))) (if (member "done" status) (funcall callback causes ex-phase) (if phase (progn (setq ex-phase phase))) (setq causes (append causes (list response))))))((dict "id" "134" "session" "4a471f61-529b-4398-aa85-59891c1c8fde" "status" ("done")))
  nrepl--dispatch-response((dict "id" "134" "session" "4a471f61-529b-4398-aa85-59891c1c8fde" "status" ("done")))
  nrepl-client-filter(#<process nrepl-connection> "d2:id3:1347:session36:4a471f61-529b-4398-aa85-59891c1c8fde6:statusl8:no-erroreed2:id3:1347:session36:4a471f61-529b-4398-aa85-59891c1c8fde6:statusl4:doneee")

Steps to reproduce the problem

  1. Create a simple hello world ClojureScript project from the quick start tutorial.
  2. Evaluate any form that throws an exception either in the REPL buffer or in the source buffer. For example:
(throw (ex-info "Error" {:some "Data"}))

;; or

(ffirst [1])

Notes after some debugging

  1. The error is signaled from the cider-stacktrace-render-cause function, because class is nil in the expression (propertize class 'font-lock-face class-face 'mouse-face 'highlight).
  2. I tried to comment the problematic expression, the error is gone but the *cider-error* buffer shows not very useful information:
Image

Environment & Version information

CIDER version information

;; CIDER 1.18.0 (Athens), nREPL 1.3.1
;; Clojure 1.12.0, Java 23.0.2

Lein / Clojure CLI version

Clojure CLI 1.12

Emacs version

GNU Emacs 31.0.50 (build 1, aarch64-apple-darwin24.4.0, NS appkit-2575.50 Version 15.4.1 (Build 24E263)) of 2025-04-29

Operating system

MacOS

JDK distribution

openjdk version "23.0.2" 2025-01-21
OpenJDK Runtime Environment Homebrew (build 23.0.2)
OpenJDK 64-Bit Server VM Homebrew (build 23.0.2, mixed mode, sharing)

@bbatsov bbatsov added the bug label May 24, 2025
@bbatsov
Copy link
Member

bbatsov commented May 24, 2025

Hmm, seems like some weird regression as the stacktrace middlware doesn't support ClojureScript at all and this window should not be triggered for ClojureScript errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants