Skip to content

Commit 1f09098

Browse files
[stacktrace] Allow inspecting ex-data directly
1 parent 25792e6 commit 1f09098

File tree

5 files changed

+62
-32
lines changed

5 files changed

+62
-32
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
- Stop vendoring Puget dependency. You can still use `puget` pretty-printer in CIDER, but you need to depend on Puget explicitly. If Puget is not found on the classpath, CIDER will revert to `clojure.pprint/pprint` for pretty-printing.
2222
- [#3777](https://github.com/clojure-emacs/cider/issues/3777): Inspector no longer displays parsed Javadoc for Java classes and members.
2323
- [#3790](https://github.com/clojure-emacs/cider/issues/3790): Stacktrace: show messages and data for all exception causes by default.
24+
- [#3807](https://github.com/clojure-emacs/cider/issues/3807): Stacktrace: make exception data individually inspectable.
2425
- [#3789](https://github.com/clojure-emacs/cider/issues/3789): Refactor and simplify exception handling.
2526
- [#3789](https://github.com/clojure-emacs/cider/issues/3796): Completion: disable client-side sorting (defer to backend-provided candidate order).
2627
- [#3797](https://github.com/clojure-emacs/cider/issues/3797): Completion: enable `cider-completion-style` by default (this enables richer completion suggestions where candidates don't have to strictly match the prefix).

cider-inspector.el

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,17 @@ See `cider-sync-request:inspect-push' and `cider-inspector--render-value'"
252252
(push (point) cider-inspector-location-stack)
253253
(cider-inspector--render-value result :next-inspectable))))
254254

255-
(defun cider-inspector-inspect-last-exception (index)
256-
"Inspects the exception in the cause stack identified by INDEX."
255+
(defun cider-inspector-inspect-last-exception (index &optional ex-data)
256+
"Inspects the exception in the cause stack identified by INDEX.
257+
If EX-DATA is true, inspect ex-data of the exception instead."
257258
(interactive)
258259
(cl-assert (numberp index))
259-
(let ((result (cider-sync-request:inspect-last-exception index)))
260+
(let ((result (cider-nrepl-send-sync-request
261+
`("op" "inspect-last-exception"
262+
"index" ,index
263+
,@(when ex-data
264+
`("ex-data" "true")))
265+
(cider-current-repl))))
260266
(when (nrepl-dict-get result "value")
261267
(setq cider-inspector-location-stack nil)
262268
(cider-inspector--render-value result :next-inspectable))))
@@ -423,14 +429,6 @@ current-namespace."
423429
(cider-nrepl-send-sync-request `("op" "inspect-previous-sibling")
424430
(cider-current-repl)))
425431

426-
;;;###autoload
427-
(defun cider-sync-request:inspect-last-exception (index)
428-
"Inspects the exception in the cause stack identified by INDEX."
429-
(cl-assert (numberp index))
430-
(cider-nrepl-send-sync-request `("op" "inspect-last-exception"
431-
"index" ,index)
432-
(cider-current-repl)))
433-
434432
(defun cider-sync-request:inspect-next-sibling ()
435433
"Inspect the next sibling value within a sequential parent."
436434
(cider-nrepl-send-sync-request `("op" "inspect-next-sibling")

cider-stacktrace.el

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -796,27 +796,48 @@ the NAME. The whole group is prefixed by string INDENT."
796796

797797
(declare-function cider-inspector-inspect-last-exception "cider-inspector")
798798

799-
(defun cider-stacktrace--inspect-class (event)
800-
"Mouse handler for EVENT."
799+
(defun cider-stacktrace--inspect-mouse (event &optional ex-data)
800+
"Mouse handler for EVENT.
801+
If EX-DATA is true, inspect ex-data of the exception instead."
801802
(interactive "e")
802803
(let* ((pos (posn-point (event-end event)))
803804
(window (posn-window (event-end event)))
804805
(buffer (window-buffer window))
805806
(inspect-index (with-current-buffer buffer
806807
(get-text-property pos 'inspect-index))))
807-
(cider-inspector-inspect-last-exception inspect-index)))
808+
(cider-inspector-inspect-last-exception inspect-index ex-data)))
808809

809-
(defun cider-stacktrace--inspect-class-kbd ()
810-
"Keyboard handler."
810+
(defun cider-stacktrace--inspect-kbd (&optional ex-data)
811+
"Keyboard handler.
812+
If EX-DATA is true, inspect ex-data of the exception instead."
811813
(interactive)
812814
(when-let ((inspect-index (get-text-property (point) 'inspect-index)))
813-
(cider-inspector-inspect-last-exception inspect-index)))
815+
(cider-inspector-inspect-last-exception inspect-index ex-data)))
816+
817+
(defun cider-stacktrace--inspect-ex-data-mouse (event)
818+
"Mouse handler for EVENT."
819+
(interactive "e")
820+
(cider-stacktrace--inspect-mouse event t))
821+
822+
(defun cider-stacktrace--inspect-ex-data-kbd ()
823+
"Keyboard handler."
824+
(interactive)
825+
(cider-stacktrace--inspect-kbd t))
814826

815827
(defvar cider-stacktrace-exception-map
816828
(let ((map (make-sparse-keymap)))
817-
(define-key map [mouse-1] #'cider-stacktrace--inspect-class)
818-
(define-key map (kbd "p") #'cider-stacktrace--inspect-class-kbd)
819-
(define-key map (kbd "i") #'cider-stacktrace--inspect-class-kbd)
829+
(define-key map [mouse-1] #'cider-stacktrace--inspect-mouse)
830+
(define-key map (kbd "p") #'cider-stacktrace--inspect-kbd)
831+
(define-key map (kbd "i") #'cider-stacktrace--inspect-kbd)
832+
(define-key map (kbd "RET") #'cider-stacktrace--inspect-kbd)
833+
map))
834+
835+
(defvar cider-stacktrace-ex-data-map
836+
(let ((map (make-sparse-keymap)))
837+
(define-key map [mouse-1] #'cider-stacktrace--inspect-ex-data-mouse)
838+
(define-key map (kbd "p") #'cider-stacktrace--inspect-ex-data-kbd)
839+
(define-key map (kbd "i") #'cider-stacktrace--inspect-ex-data-kbd)
840+
(define-key map (kbd "RET") #'cider-stacktrace--inspect-ex-data-kbd)
820841
map))
821842

822843
(defun cider-stacktrace-render-cause (buffer cause num note &optional inspect-index)
@@ -839,10 +860,10 @@ make INSPECT-INDEX actionable if present."
839860
,cider-stacktrace-exception-map)
840861
(insert (format "%d. " num)
841862
(propertize note 'font-lock-face 'font-lock-comment-face) " "
842-
(propertize class 'font-lock-face class-face 'mouse-face 'highlight)))
863+
(propertize class 'font-lock-face class-face 'mouse-face 'highlight)
864+
"\n"))
843865
;; Detail level 1: message + ex-data
844866
(cider-propertize-region '(detail 1)
845-
(insert "\n")
846867
(if (equal class "clojure.lang.Compiler$CompilerException")
847868
(cider-stacktrace-render-compile-error buffer cause)
848869
(cider-stacktrace-emit-indented
@@ -859,18 +880,25 @@ make INSPECT-INDEX actionable if present."
859880
(cider-stacktrace--emit-spec-problems spec (concat indent " ")))
860881
(when data
861882
(insert "\n")
862-
(cider-stacktrace-emit-indented data indent nil t)))
883+
(cider-propertize-region `(inspect-index
884+
,inspect-index
885+
keymap
886+
,cider-stacktrace-ex-data-map
887+
mouse-face
888+
highlight)
889+
(cider-stacktrace-emit-indented data indent nil t)))
890+
(insert "\n"))
863891
;; Detail level 2: stacktrace
864892
(cider-propertize-region '(detail 2)
865893
(let ((beg (point))
866894
(bg `(:background ,cider-stacktrace-frames-background-color :extend t)))
867895
(dolist (frame stacktrace)
868-
(insert "\n")
869-
(cider-stacktrace-render-frame buffer frame))
896+
(cider-stacktrace-render-frame buffer frame)
897+
(insert "\n"))
870898
(overlay-put (make-overlay beg (point)) 'font-lock-face bg)))
871899
;; Add line break between causes, even when collapsed.
872900
(cider-propertize-region '(detail 0)
873-
(insert "\n\n")))))))
901+
(insert "\n")))))))
874902

875903
(defun cider-stacktrace-initialize (causes)
876904
"Set and apply CAUSES initial visibility, filters, and cursor position."
Loading

doc/modules/ROOT/pages/usage/dealing_with_errors.adoc

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,18 +212,21 @@ for instance:
212212

213213
== Inspector integration
214214

215-
Within `*cider-error*`, when clicking directly a top-level exception (any of them in the cause chain),
216-
that specific exception will be inspected with the CIDER xref:debugging/inspector.adoc[Inspector].
215+
Within `*cider-error*`, when clicking directly a top-level exception (any of
216+
them in the cause chain), that specific exception will be inspected with the
217+
CIDER xref:debugging/inspector.adoc[Inspector]. You can also click on the
218+
rendered exception data to inspect it directly.
217219

218-
This allows you to better understand intrincate `ex-data`.
220+
This clicking is defined and customizable in `cider-stacktrace-exception-map`
221+
and `cider-stacktrace-ex-data-map`.
219222

220-
This clicking is defined and customizable in `cider-stacktrace-exception-map`, which has the following defaults:
223+
image::cider-stacktrace-inspect.gif[Inspect the exceptions and ex-data]
221224

222225
=== Keybindings
223226

224227
|===
225228
| Action | Description
226229

227-
| kbd:[click] or kbd:[i] or kbd:[p]
228-
| Open the given exception in the Inspector.
230+
| kbd:[click] or kbd:[i] or kbd:[p] or kbd:[Return]
231+
| Open the given exception or ex-data in the Inspector.
229232
|===

0 commit comments

Comments
 (0)