emacs-ycmd
emacs-ycmd copied to clipboard
Improve diagnostics when ycmd-server process launch fails
If ycmd--start-server fails to launch the ycmd process (e.g. because it's not installed), the current diagnostics in *Messages* are far from helpful:
Error running timer: (file-error "Spawning child process" "Invalid argument")
To improve this we need to be a bit more proactive in catching the error and adding our own text describing what happened. We might use something like this in ycmd--start-server:
(proc
(condition-case err
(apply #'start-process ycmd--server-process-name proc-buff
server-program+args)
(error
(error "Error starting ycmd server process: %s" (error-message-string err)))))
Should be easy to get in place.
Good idea to be more proactive in catching errors.
AFAIK your code snippet would only catch if the program is not found (here python). In ycmd's case the ycmd python module is an argument. In that case I don't get an emacs error and the condition-case would not catch the error. In that case we get an error from python, which is visible in the *ycmd-server* buffer.
Yes, you're absolutely right, the snippet I included is pretty narrow. It had taken me a while to track down the source of the problem I was seeing, and I just wanted to make sure I had a record of the problem :)
I'm open to any suggestions or ideas about how we should approach this. I've only got limited experience with elisp error handling, so my ideas might be naive or just wrong. However, I'll probably put together a PR just so we have something concrete to discuss.
It seems like a critical place for better error reporting is in functions launched by timers (i.e. like the one I initially tracked down). When those report errors, we don't get very useful stack traces, so it would be helpful if they intercepted errors and supplemented them with details about where they come from in our terms. In practical terms, this seems to mean:
ycmd--on-idle-changeycmd--on-unparsed-buffer-focusycmd--on-server-timeoutycmd--keepalive
Maybe the simplest thing to do is create versions of the timer function run-at-time and run-with-timer that catch errors and add information about the context of the call.
I was thinking also about handling the errors better within the ycmd--request function. But I'm not sure how to implement exactly and whether it will work. I'm not so sure about creating new version of run-at-time and run-with-timer. I think we should identify the exact places where an error can pop up. My setup was working most of the time and I didn't have too many errors whose sources I could not identify.
I have not much time these days to look into ycmd stuff but I'm happy to discuss within a PR.