Skip to content

Commit

Permalink
Avoid cider--error-phase-of-last-exception recursive loop (#3607)
Browse files Browse the repository at this point in the history
Fixes #3605
  • Loading branch information
vemv authored Jan 17, 2024
1 parent 21cdfeb commit f7f8e2c
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 14 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## master (unreleased)

### Bugs fixed

- [#3605](https://github.com/clojure-emacs/cider/issues/3605): avoid `cider--error-phase-of-last-exception` recursive loop.

## 1.13.0 (2024-01-14)

### Changes
Expand Down
52 changes: 38 additions & 14 deletions cider-eval.el
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,8 @@ and ON-SUCCESS-CALLBACK an optional callback.
The handler simply inserts the result value in BUFFER."
(let ((eval-buffer (current-buffer))
(res "")
(failed nil))
(failed nil)
(error-phase-requested nil)) ;; avoid requesting the phase more than once - can happen if there are errors during the phase nrepl sync request.
(nrepl-make-response-handler (or buffer eval-buffer)
;; value handler:
(lambda (_buffer value)
Expand All @@ -781,7 +782,10 @@ The handler simply inserts the result value in BUFFER."
(when (and source-buffer
(listp bounds)) ;; if it's a list, it represents bounds, otherwise it's a string (code) and we can't display the overlay
(with-current-buffer source-buffer
(let* ((phase (cider--error-phase-of-last-exception buffer))
(let* ((phase (if error-phase-requested
nil
(setq error-phase-requested t)
(cider--error-phase-of-last-exception buffer)))
(end (or (car-safe (cdr-safe bounds)) bounds))
(end (when end
(copy-marker end))))
Expand Down Expand Up @@ -845,12 +849,16 @@ REPL buffer. This is controlled via
(when-let ((conn (with-current-buffer buffer
(cider-current-repl))))
(when (cider-nrepl-op-supported-p "analyze-last-stacktrace" conn)
(when-let* ((result (nrepl-send-sync-request (thread-last (map-merge 'list
'(("op" "analyze-last-stacktrace"))
(cider--nrepl-print-request-map fill-column))
(seq-mapcat #'identity))
conn)))
(nrepl-dict-get result "phase"))))))
(let ((nrepl-err-handler (lambda (&rest _))) ;; ignore any errors during this request to avoid any recursion
(nrepl-sync-request-timeout 4)) ;; ensure that this feature cannot possibly create an overly laggy UX
(when-let* ((result (nrepl-send-sync-request (thread-last (map-merge 'list
'(("op" "analyze-last-stacktrace"))
(cider--nrepl-print-request-map fill-column))
(seq-mapcat #'identity))
conn
'abort-on-input ;; favor responsiveness over this feature, in case something went wrong.
)))
(nrepl-dict-get result "phase")))))))

(defcustom cider-inline-error-message-function #'cider--shorten-error-message
"A function that will shorten a given error message,
Expand Down Expand Up @@ -905,17 +913,24 @@ when `cider-auto-inspect-after-eval' is non-nil."
(beg (when beg (copy-marker beg)))
(end (when end (copy-marker end)))
(fringed nil)
(res ""))
(res "")
(error-phase-requested nil)) ;; avoid requesting the phase more than once - can happen if there are errors during the phase nrepl sync request.
(nrepl-make-response-handler (or buffer eval-buffer)
;; value handler:
(lambda (_buffer value)
(setq res (concat res value))
(cider--display-interactive-eval-result res 'value end))
;; stdout handler:
(lambda (_buffer out)
(cider-emit-interactive-eval-output out))
;; stderr handler:
(lambda (buffer err)
(cider-emit-interactive-eval-err-output err)

(let ((phase (cider--error-phase-of-last-exception buffer)))
(let ((phase (if error-phase-requested
nil
(setq error-phase-requested t)
(cider--error-phase-of-last-exception buffer))))

(cider--maybe-display-error-as-overlay phase err end)

Expand All @@ -927,6 +942,7 @@ when `cider-auto-inspect-after-eval' is non-nil."
;; the error is 'right there' in the current line
;; and needs no jumping:
phase)))
;; done handler:
(lambda (buffer)
(if beg
(unless fringed
Expand All @@ -946,7 +962,8 @@ when `cider-auto-inspect-after-eval' is non-nil."
"Make a load file handler for BUFFER.
Optional argument DONE-HANDLER lambda will be run once load is complete."
(let ((eval-buffer (current-buffer))
(res ""))
(res "")
(error-phase-requested nil)) ;; avoid requesting the phase more than once - can happen if there are errors during the phase nrepl sync request.
(nrepl-make-response-handler (or buffer eval-buffer)
(lambda (buffer value)
(cider--display-interactive-eval-result value 'value)
Expand All @@ -963,7 +980,10 @@ Optional argument DONE-HANDLER lambda will be run once load is complete."
;; 1.- Jump to the error line:
(cider-handle-compilation-errors err eval-buffer)
(with-current-buffer eval-buffer
(let* ((phase (cider--error-phase-of-last-exception buffer))
(let* ((phase (if error-phase-requested
nil
(setq error-phase-requested t)
(cider--error-phase-of-last-exception buffer)))
;; 2.- Calculate the overlay position, which is the point (per the previous jump),
;; and then end-of-line (for ensuring the overlay will be rendered properly):
(end (save-excursion
Expand Down Expand Up @@ -1072,7 +1092,8 @@ and SOURCE-BUFFER the original buffer
This is used by pretty-printing commands."
;; NOTE: cider-eval-register behavior is not implemented here for performance reasons.
;; See https://github.com/clojure-emacs/cider/pull/3162
(let ((chosen-buffer (or buffer (current-buffer))))
(let ((chosen-buffer (or buffer (current-buffer)))
(error-phase-requested nil)) ;; avoid requesting the phase more than once - can happen if there are errors during the phase nrepl sync request.
(nrepl-make-response-handler
chosen-buffer
;; value handler:
Expand All @@ -1087,7 +1108,10 @@ This is used by pretty-printing commands."
(when (and source-buffer
(listp bounds)) ;; if it's a list, it represents bounds, otherwise it's a string (code) and we can't display the overlay
(with-current-buffer source-buffer
(let* ((phase (cider--error-phase-of-last-exception buffer))
(let* ((phase (if error-phase-requested
nil
(setq error-phase-requested t)
(cider--error-phase-of-last-exception buffer)))
(end (or (car-safe (cdr-safe bounds)) bounds))
(end (when end
(copy-marker end))))
Expand Down

0 comments on commit f7f8e2c

Please sign in to comment.