-
-
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
Try to handle CIDER mistakes more gracefully #1617
Conversation
(defun log-cider-error (response) | ||
"Log errors caught by CIDER if you don't want to spam the REPL with stacktraces" | ||
(with-current-buffer (get-buffer-create "*cider-error-log*") | ||
(setq buffer-read-only nil) |
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.
Don't set this variable. Let-bind inhibit-read-only
to t instead.
Thanks. 👍 Could you show an example of what this would look like? And what's the current behaviour? Also, the function names need to be namespaced. |
Yeah sure, here's a screencast of the before: Any preference on where the error management should live? I just put them in the nrepl-client code because that was proximal to where the errors were coming into the system |
Note that the real problem in a way is this one - #1420 Ideally people would get stacktrace buffers when using sync nREPL requests and there won't be a need for another different error buffer. I'll go over your code a bit later. |
Interesting...I'll try and make a version where everything goes through the standard stacktrace buffer. I think that it'll be beneficial to ultimately have some kind of tiered error reporting system with varying degrees of interaction, attention, and logging. This would require doing some analysis of the stack traces at the middleware level and then have some standard hierarchy of error messages to use in the reply's |
Here's a demonstration of error reporting using a stacktrace buffer (the vanilla one, not the fancy one that relies on the stacktrace middleware). It was pretty much just a two line change in the existing code. Not a huge fan of it for this particular problem, but would be a nice option to have for sync request errors in general. In order to get it to use the fancy stacktrace middleware, I was planning on keeping a cache of the caught java.lang.Exception's and stuffing a key to that cache into the reply packet we send back to the CIDER side. That way the CIDER side can request a StackTrace analysis after the fact without needing *e to be bound and it wouldn't matter if *e got changed out from underneath us or anything like that. (The error catching refactorings/abstractions that we've been discussing would be pretty useful for this to hide all this complexity) |
This video is private. :-) |
oops, my bad, give it a try again: On Thu, Mar 17, 2016 at 1:56 AM, Bozhidar Batsov [email protected]
|
Thanks!
|
Looks ok.
Why not? I'd rather use something generic instead of having some special buffer type for middleware errors. I see the point of your initial solution, but it seems to me that's it's a bit excessive (and I don't like that the error buffer combines different data, that while useful debugging is likely going to confuse most users). I do agree, however, that it makes sense to display some message in the minibuffer saying that an "internal cider error occurred" or something like this in such situations, as obviously just dumping/showing a stacktrace is not terribly informative either.
Yeah, I guess something like this might work. |
@@ -1336,6 +1333,26 @@ The default buffer name is *nrepl-error*." | |||
(set-window-point win (point-max))) | |||
(setq buffer-read-only t))) | |||
|
|||
;;TODO: IMPROVE ON THIS, pull out buffer name into a variable, make formatting serious, etc. | |||
(defun log-cider-error (response) | |||
"Log errors caught by CIDER if you don't want to spam the REPL with stacktraces" |
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.
Btw, you should check out https://www.gnu.org/software/emacs/manual/html_node/elisp/Documentation-Tips.html (or use M-x checkdoc
).
Thanks for the pointers and documentation resources on the Elisp code! I'll definitely update with better organized and documented code once I have a more concrete idea of what to implement and what parts of the system it will touch. Ideally I'd like to pull all of the error handling related code out into a different namespace but I'm worried to make drastic changes since I don't understand Elisp or the CIDER side of things well at all, so I'll probably just start small.
Yeah, that's a good point...I don't have any compelling arguments for my case to be honest and the examples I put together are more just for brainstorming rather than a final destination. The next prototype that I'm planning will let you coarsely tune the error response, so maybe we'll be able to figure out what the best direction would be by getting some real world usage under our belts. I will say that in light of the bug report in CIDER-nREPL that prompted this branch, it would be nice if bug reports would contain the request packet, reply packet, AND the stacktrace instead of just the stacktrace so that it would be a bit easier to replicate the problem. You're right that it is confusing though, so I'll have to think more about how to balance UI with QA needs. Thanks again for the input! |
Here's the demo of a sync-request error displayed in the nice stacktrace-op dependent buffer as you mentioned: I just added:
From there, I basically just used the same internals that we use on the CIDER side for handling the eval-type errors. Actually, there's very little that's new in these changes at all, just a couple lines here and there that are different. I've pushed the CIDER-nREPL code to my repo under the store-stacktrace branch. It's very very (embarrassingly) rudimentary, so I didn't want to send over a PR, but let me know if it's going in the right direction and I'll try to polish it up and get it out soon. Thanks! |
Actually, now that I think about it, we don't even need the separate Stacktrace op, could just pass in an optional storage-key...If no storage key passed in, return *e. If key passed in, return stored stacktrace. If we did it that way, there'd be even fewer overall changes |
Looks good!
Sounds like a good plan to me.
Indeed. Finding the right balance is always hard. On a related note - the UI of the messages log itself should eventually be improved - e.g. it might be nice to be able to filter out certain message types, highlight requests and responses, font-lock errors differently, and fix the alignment of dictionaries... If only we had time. :-) |
Sync-call errors do not bind *e unlike eval-call errors. This made it impossible to use the stacktrace middleware to create the nicely analyzed and formatted stacktrace buffer (see Issue clojure-emacs#1420 clojure-emacs#1420). In order to rectify this, the nREPL code was modified slightly to store sync-call related errors and provide a mechanism for the stacktrace middleware to retrieve and process these stored exceptions. This results in the ability for sync-call related errors to be analyzed and presented using the standard stacktract buffer.
The u/err-info function will now automatically store exceptions in simple map based single-use data store. This will allow the stacktrace middleware to act on Exceptions that were not bound to *e. See bug 1420 in CIDER: clojure-emacs/cider#1420. See also CIDER PR 1617: clojure-emacs/cider#1617
The u/err-info function will now automatically store exceptions in simple map-based, single-use, FIFO-expiring data store. This will allow the stacktrace middleware to act on Exceptions that were not bound to *e. See bug 1420 in CIDER: clojure-emacs/cider#1420. See also CIDER PR 1617: clojure-emacs/cider#1617
The u/err-info function will now automatically store exceptions in simple map-based, single-use, FIFO-expiring data store. This will allow the stacktrace middleware to act on Exceptions that were not bound to *e. See bug 1420 in CIDER: clojure-emacs/cider#1420. See also CIDER PR 1617: clojure-emacs/cider#1617
The u/err-info function will now automatically store exceptions in simple map-based, single-use, FIFO-expiring data store. This will allow the stacktrace middleware to act on Exceptions that were not bound to *e. See bug 1420 in CIDER: clojure-emacs/cider#1420. See also CIDER PR 1617: clojure-emacs/cider#1617
The u/err-info function will now automatically store exceptions in simple map-based, single-use, FIFO-expiring data store. This will allow the stacktrace middleware to act on Exceptions that were not bound to *e. See bug 1420 in CIDER: clojure-emacs/cider#1420. See also CIDER PR 1617: clojure-emacs/cider#1617
Submitting a different pull request which doesn't require the whole "storage" mess. This PR can be rejected. |
Not ready yet, but thought I'd see what you guys thought before going any further
Before submitting a PR make sure the following things have been done:
make test
)M-x checkdoc
warningsThanks!
Unless specifically coded into the sync request, errors result in
stacktraces being thrown onto the REPL and focus changing to the REPL
buffer. These changes just log the exception info into a buffer and
notify the user of this in the message area. Easiest way to see how this
works is to select a region with unbalanced parens and then call a
cider-format-region-edn.