-
-
Notifications
You must be signed in to change notification settings - Fork 645
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
Avoid cider--error-phase-of-last-exception
recursive loop
#3607
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
|
@@ -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)))) | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why 4? That's a oddly specific number. :-) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 4 - ample enough to give it time to be slow (especially if there was some sort of cache to be hit), tight enough to not negatively impact the UX I'd be fine with 3 or 5 as well 😄 |
||
(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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When I reproduced the issue, 'abort-on-input made it less terrible, so it seems wise to leave this here. |
||
))) | ||
(nrepl-dict-get result "phase"))))))) | ||
|
||
(defcustom cider-inline-error-message-function #'cider--shorten-error-message | ||
"A function that will shorten a given error message, | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the main fix I could only immediately reproduce it for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You might want to add some comment explaining the need for the toggling between |
||
nil | ||
(setq error-phase-requested t) | ||
(cider--error-phase-of-last-exception buffer)))) | ||
|
||
(cider--maybe-display-error-as-overlay phase err end) | ||
|
||
|
@@ -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 | ||
|
@@ -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) | ||
|
@@ -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 | ||
|
@@ -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: | ||
|
@@ -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)))) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems this
if
is duplicated a few times, so it might be good to make it some utility function instead.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if an abstraction could capture the necessary pattern
At most I can imagine a macro that ensured that a local variable
error-phase-requested
exists.