all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "João Távora" <joaotavora@gmail.com>
To: Spencer Baugh <sbaugh@janestreet.com>
Cc: Dmitry Gutov <dmitry@gutov.dev>, Eli Zaretskii <eliz@gnu.org>,
	app-emacs-dev@janestreet.com, 70724@debbugs.gnu.org
Subject: bug#70724: 29.2.50; eglot-reconnect errors when the project is deleted
Date: Thu, 21 Nov 2024 23:36:50 +0000	[thread overview]
Message-ID: <CALDnm508PGjV9Fh2zabZxPtVrtin3EtT7s7pSm3kLp8kryONqQ@mail.gmail.com> (raw)
In-Reply-To: <iered34tinb.fsf@janestreet.com>

[-- Attachment #1: Type: text/plain, Size: 11722 bytes --]

So, the error is explanatory, no??  As far as I can tell your original
patch also signalled an error, and that error happened in the sentinel.

If you want to avoid this error and silently proceed, for the benefit
of your particular workflow, write a project backend  that keeps its
vital information despite having lost its file system backing.

Or, maybe better, write some advice to eglot-autoreconnect which
is an external function (and thus offers some stability guarantee of
its interface).  eglot-reconnect takes the server as argument and
you can query the project to know if its still valid or not and noop
in the case it's been deleted from the filesystem.  But this is too
specific to generalize in Eglot.  I for one like to be warned of these
error, because for me having a connected-to project suddenly
deleted in an exception, it's not the rule.

João



On Thu, Nov 21, 2024, 20:51 Spencer Baugh <sbaugh@janestreet.com> wrote:

> João Távora <joaotavora@gmail.com> writes:
>
> > Explain your scenario, please.  And note that if you take the rug from
> > underneath Eglot it will error, period.  That's by design.   I'm not
> > willing to contort the code to do  anything more than provide a
> > more or less understandable error message for such (relatively rare)
> > rug pulling.  IOW sentinels erroring is part of Emacs life and not a
> > bug in itself,  it's the error message that I'm willing to help ensure is
> > clear.
>
> I use (the equivalent of) git worktrees to have one repo checkout per
> branch that I'm working on.  As I finish work on a branch, I delete the
> worktree with a shell command outside of Emacs.  Thus I hit this error
> several times a day, depending on how productive I am.
>
> (The same workflow is used by ~everyone at my employer, and before we
> can use Eglot widely, it would be ideal to get rid of this frequent
> error)
>
> > Please provide a backtrace and say if it's obtained with the very
> > same recipe in the beginning of the bug report.
> >
>
> Sure, here's the backtrace with the patch in your last email.  It is
> obtained with the very same recipe in the beginning of the bug report: I
> opened an (OCaml) file, did M-x eglot (starting ocaml-lsp), deleted the
> directory, and it proceeded as I said in the beginning of the bug
> report.
>
> Debugger entered--Lisp error: (error "[eglot] Project at
> `/usr/local/home/sbaugh/workspaces/fe-880764/+share+/' is gone!")
>   signal(error ("[eglot] Project at
> `/usr/local/home/sbaugh/workspaces/fe-880764/+share+/' is gone!"))
>   error("[eglot] %s" "Project at
> `/usr/local/home/sbaugh/workspaces/fe-880764/+share+/' is gone!")
>   eglot--error("Project at `%s' is gone!"
> "/usr/local/home/sbaugh/workspaces/fe-880764/+share+/")
>   (if (file-exists-p default-directory) (project-name project)
> (eglot--error "Project at `%s' is gone!" default-directory))
>   (let* ((default-directory (project-root project)) (nickname (if
> (file-exists-p default-directory) (project-name project) (eglot--error
> "Project at `%s' is gone!" default-directory))) (readable-name (format
> "EGLOT (%s/%s)" nickname managed-modes)) server-info (contact (if
> (functionp contact) (funcall contact) contact)) (initargs (cond ((keywordp
> (car contact)) contact) ((integerp (car (cdr contact))) (setq server-info
> (list (format "%s:%s" ... ...))) (list ':process #'(lambda nil ...))) ((and
> (stringp (car contact)) (cl-find-if #'... contact)) (setq server-info (list
> "<inferior process>")) (list ':process (jsonrpc-autoport-bootstrap
> readable-name contact :connect-args '...))) ((stringp (car contact)) (let*
> ((probe ...) (more-initargs ...) (contact ...)) (cons ':process (cons ...
> more-initargs)))))) (spread #'(lambda (fn) #'(lambda (server method params)
> (let ... ...)))) (server (apply #'make-instance class :name readable-name
> :events-buffer-config eglot-events-buffer-config :notification-dispatcher
> (funcall spread #'eglot-handle-notification) :request-dispatcher (funcall
> spread #'eglot-handle-request) :on-shutdown #'eglot--on-shutdown initargs))
> (canceled nil) (tag (make-symbol "connected-catch-tag"))) (if server-info
> (progn (jsonrpc--debug server "Running language server: %s" (string-join
> server-info " ")))) (let* ((v server)) (\(setf\ eglot--saved-initargs\)
> initargs v)) (let* ((v server)) (\(setf\ eglot--project\) project v)) (let*
> ((v server)) (\(setf\ eglot--project-nickname\) nickname v)) (let* ((v
> server)) (\(setf\ eglot--languages\) (let* ((--cl-var-- managed-modes) (m
> nil) (--cl-var-- language-ids) (l nil) (--cl-var-- nil)) (while (and (consp
> --cl-var--) (progn (setq m ...) (consp --cl-var--))) (setq l (car
> --cl-var--)) (setq --cl-var-- (cons (cons m l) --cl-var--)) (setq
> --cl-var-- (cdr --cl-var--)) (setq --cl-var-- (cdr --cl-var--))) (nreverse
> --cl-var--)) v)) (run-hook-with-args 'eglot-server-initialized-hook server)
> (unwind-protect (condition-case _quit (let ((retval (catch tag
> (jsonrpc-async-request server :initialize ... :success-fn ... :timeout
> eglot-connect-timeout :error-fn ... :timeout-fn ...) (cond ... ...))))
> (cond ((consp retval) (let* (...) (if ... ... ...))) ((null retval) (let
> nil (eglot--message "Waiting in background for server `%s'" ...) nil)) (t
> (let nil server)))) (quit (jsonrpc-shutdown server) (setq canceled 'quit)))
> (setq tag nil)))
>   eglot--connect((tuareg-mode) #s(jane-fe-project :workspace
> "/usr/local/home/sbaugh/workspaces/fe-880764/+share+/" :vc (vc Hg
> "/usr/local/home/sbaugh/workspaces/fe-880764/+share+/")) eglot-lsp-server
> (:process (closure ((contact "dispatch_ocaml_lsp.exe" "open! Core" "dev")
> (server-info "dispatch_ocaml_lsp.exe" "open! Core" "dev") (readable-name .
> "EGLOT (dune-add-disable-file-watcher-rpc/(tuareg-mode))")
> tramp-ssh-controlmaster-options tramp-use-ssh-controlmaster-options) nil
> (let ((default-directory default-directory)
> (tramp-use-ssh-controlmaster-options 'suppress)
> (tramp-ssh-controlmaster-options "-o ControlMaster=no -o
> ControlPath=none")) (make-process :name readable-name :command (setq
> server-info (eglot--cmd contact)) :connection-type 'pipe :coding
> 'utf-8-emacs-unix :noquery t :stderr (get-buffer-create (format "*%s
> stderr*" readable-name)) :file-handler t)))) ("tuareg"))
>   eglot-reconnect(#<eglot-lsp-server eglot-lsp-server-18f8056>)
>   (cond ((eglot--shutdown-requested server) t) ((not
> (eglot--inhibit-autoreconnect server)) (eglot--warn "Reconnecting after
> unexpected server exit.") (eglot-reconnect server)) ((timerp
> (eglot--inhibit-autoreconnect server)) (eglot--warn "Not auto-reconnecting,
> last one didn't last long.")))
>   eglot--on-shutdown(#<eglot-lsp-server eglot-lsp-server-18f8056>)
>   funcall(eglot--on-shutdown #<eglot-lsp-server eglot-lsp-server-18f8056>)
>   (unwind-protect (mapc #'(lambda (jsonrpc-lambda-elem168) (apply
> #'(lambda (_id _method _success-fn error-fn _timer) (funcall error-fn
> '(:code -1 :message "Server died"))) jsonrpc-lambda-elem168))
> (jsonrpc--continuations connection)) (jsonrpc--message "Server exited with
> status %s" (process-exit-status proc)) (delete-process proc) (let* ((p (and
> t (slot-value connection '-autoport-inferior)))) (if p (delete-process p)
> nil)) (funcall (jsonrpc--on-shutdown connection) connection))
>   (progn (save-current-buffer (set-buffer (jsonrpc-events-buffer
> connection)) (let ((inhibit-read-only t)) (insert
> "\n----------b---y---e---b---y---e----------\n"))) (mapc #'(lambda
> (jsonrpc-lambda-elem167) (apply #'(lambda (_id _method _success-fn
> _error-fn timer) (if timer (progn (cancel-timer timer))))
> jsonrpc-lambda-elem167)) (jsonrpc--continuations connection)) (maphash
> #'(lambda (_ triplet) (progn (ignore (consp triplet)) (let* ((x919
> (cdr-safe triplet))) (progn (ignore (consp x919)) (let* ((x920 (car-safe
> x919)) (x921 (cdr-safe x919))) (progn (ignore (consp x921)) (let* ((x923
> (cdr-safe x921))) (progn (ignore (null x923)) (let ((timer x920)) (if timer
> (progn (cancel-timer timer)))))))))))) (jsonrpc--deferred-actions
> connection)) (process-put proc 'jsonrpc-sentinel-cleanup-started t)
> (unwind-protect (mapc #'(lambda (jsonrpc-lambda-elem168) (apply #'(lambda
> (_id _method _success-fn error-fn _timer) (funcall error-fn '(:code -1
> :message "Server died"))) jsonrpc-lambda-elem168)) (jsonrpc--continuations
> connection)) (jsonrpc--message "Server exited with status %s"
> (process-exit-status proc)) (delete-process proc) (let* ((p (and t
> (slot-value connection '-autoport-inferior)))) (if p (delete-process p)
> nil)) (funcall (jsonrpc--on-shutdown connection) connection)))
>   (if (not (process-live-p proc)) (progn (save-current-buffer (set-buffer
> (jsonrpc-events-buffer connection)) (let ((inhibit-read-only t)) (insert
> "\n----------b---y---e---b---y---e----------\n"))) (mapc #'(lambda
> (jsonrpc-lambda-elem167) (apply #'(lambda (_id _method _success-fn
> _error-fn timer) (if timer (progn (cancel-timer timer))))
> jsonrpc-lambda-elem167)) (jsonrpc--continuations connection)) (maphash
> #'(lambda (_ triplet) (progn (ignore (consp triplet)) (let* ((x919
> (cdr-safe triplet))) (progn (ignore (consp x919)) (let* ((x920 (car-safe
> x919)) (x921 (cdr-safe x919))) (progn (ignore (consp x921)) (let* ((x923
> (cdr-safe x921))) (progn (ignore (null x923)) (let ((timer x920)) (if timer
> (progn ...))))))))))) (jsonrpc--deferred-actions connection)) (process-put
> proc 'jsonrpc-sentinel-cleanup-started t) (unwind-protect (mapc #'(lambda
> (jsonrpc-lambda-elem168) (apply #'(lambda (_id _method _success-fn error-fn
> _timer) (funcall error-fn '(:code -1 :message "Server died")))
> jsonrpc-lambda-elem168)) (jsonrpc--continuations connection))
> (jsonrpc--message "Server exited with status %s" (process-exit-status
> proc)) (delete-process proc) (let* ((p (and t (slot-value connection
> '-autoport-inferior)))) (if p (delete-process p) nil)) (funcall
> (jsonrpc--on-shutdown connection) connection))))
>   (let ((connection (process-get proc 'jsonrpc-connection)))
> (jsonrpc--debug connection "Connection state change: `%s'" change) (if (not
> (process-live-p proc)) (progn (save-current-buffer (set-buffer
> (jsonrpc-events-buffer connection)) (let ((inhibit-read-only t)) (insert
> "\n----------b---y---e---b---y---e----------\n"))) (mapc #'(lambda
> (jsonrpc-lambda-elem167) (apply #'(lambda (_id _method _success-fn
> _error-fn timer) (if timer (progn (cancel-timer timer))))
> jsonrpc-lambda-elem167)) (jsonrpc--continuations connection)) (maphash
> #'(lambda (_ triplet) (progn (ignore (consp triplet)) (let* ((x919
> (cdr-safe triplet))) (progn (ignore (consp x919)) (let* ((x920 (car-safe
> x919)) (x921 (cdr-safe x919))) (progn (ignore (consp x921)) (let* ((x923
> (cdr-safe x921))) (progn (ignore (null x923)) (let (...) (if timer
> ...)))))))))) (jsonrpc--deferred-actions connection)) (process-put proc
> 'jsonrpc-sentinel-cleanup-started t) (unwind-protect (mapc #'(lambda
> (jsonrpc-lambda-elem168) (apply #'(lambda (_id _method _success-fn error-fn
> _timer) (funcall error-fn '(:code -1 :message "Server died")))
> jsonrpc-lambda-elem168)) (jsonrpc--continuations connection))
> (jsonrpc--message "Server exited with status %s" (process-exit-status
> proc)) (delete-process proc) (let* ((p (and t (slot-value connection
> '-autoport-inferior)))) (if p (delete-process p) nil)) (funcall
> (jsonrpc--on-shutdown connection) connection)))))
>   jsonrpc--process-sentinel(#<process EGLOT
> (dune-add-disable-file-watcher-rpc/(tuareg-mode))> "exited abnormally with
> code 1\n")
>

[-- Attachment #2: Type: text/html, Size: 12880 bytes --]

  reply	other threads:[~2024-11-21 23:36 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-02 19:37 bug#70724: 29.2.50; eglot-reconnect errors when the project is deleted Spencer Baugh
2024-05-04  1:09 ` Dmitry Gutov
2024-05-18  8:31   ` Eli Zaretskii
2024-05-19 15:08     ` Dmitry Gutov
2024-11-21 19:46       ` Spencer Baugh via Bug reports for GNU Emacs, the Swiss army knife of text editors
     [not found]       ` <ierplmotmxh.fsf@janestreet.com>
2024-11-21 19:49         ` João Távora
2024-11-21 19:52           ` Spencer Baugh via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-21 19:55             ` Spencer Baugh via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-21 20:14               ` João Távora
2024-11-21 20:51                 ` Spencer Baugh via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-21 23:36                   ` João Távora [this message]
2024-06-06 20:36   ` Dmitry Gutov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CALDnm508PGjV9Fh2zabZxPtVrtin3EtT7s7pSm3kLp8kryONqQ@mail.gmail.com \
    --to=joaotavora@gmail.com \
    --cc=70724@debbugs.gnu.org \
    --cc=app-emacs-dev@janestreet.com \
    --cc=dmitry@gutov.dev \
    --cc=eliz@gnu.org \
    --cc=sbaugh@janestreet.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.