From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: =?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?= Newsgroups: gmane.emacs.bugs Subject: bug#70724: 29.2.50; eglot-reconnect errors when the project is deleted Date: Thu, 21 Nov 2024 23:36:50 +0000 Message-ID: References: <8634qffrly.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="0000000000003a3d18062774becc" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="15177"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Dmitry Gutov , Eli Zaretskii , app-emacs-dev@janestreet.com, 70724@debbugs.gnu.org To: Spencer Baugh Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Nov 22 00:39:23 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1tEGle-0003mH-Ni for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 22 Nov 2024 00:39:23 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tEGlP-000645-Bu; Thu, 21 Nov 2024 18:39:08 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tEGlL-00063k-1T for bug-gnu-emacs@gnu.org; Thu, 21 Nov 2024 18:39:03 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tEGlK-0004Mx-Ly for bug-gnu-emacs@gnu.org; Thu, 21 Nov 2024 18:39:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=Date:From:In-Reply-To:References:MIME-Version:To:Subject; bh=44WuLjMigwbnCWOuz/kLh5iSKbDqD/FEC8xTP81igPc=; b=CluUQ4d89fw2a2hkxSgmnowb4OdMbFs7+pdpjWLh0XB+I6hEbsHdpKT6j2RfOt96dRs0T6SZzM3MAF8KP3T/scEfvSuOOddGtJF93hZcrgHcuKSaqHBVs2Sq6qxxWOpG8swIZRcwMfb1m4Z1quC/6ju46xs14ZdpVxK4yxtwBhGhg+9Y+w+mPxzsoRODrZliU/42FBaHAnj6KGXvRYEPY4fwBEw95L8mpu9uIyZARIOjdHPfKxvI73YNhToztSCk1svwGvw3m/Oa0vMLGh3W+LX3MKX+aLuQVaVTYq6nj+01nvCvxMCkAXdq3+bdaGza6qbm/AMfnVcVqWTrQ/Go0A==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tEGlK-0005Zk-Fw for bug-gnu-emacs@gnu.org; Thu, 21 Nov 2024 18:39:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: =?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 21 Nov 2024 23:39:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 70724 X-GNU-PR-Package: emacs Original-Received: via spool by 70724-submit@debbugs.gnu.org id=B70724.173223229221370 (code B ref 70724); Thu, 21 Nov 2024 23:39:02 +0000 Original-Received: (at 70724) by debbugs.gnu.org; 21 Nov 2024 23:38:12 +0000 Original-Received: from localhost ([127.0.0.1]:52134 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tEGkU-0005YY-GH for submit@debbugs.gnu.org; Thu, 21 Nov 2024 18:38:12 -0500 Original-Received: from mail-oi1-f179.google.com ([209.85.167.179]:59612) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tEGkR-0005Y6-35 for 70724@debbugs.gnu.org; Thu, 21 Nov 2024 18:38:08 -0500 Original-Received: by mail-oi1-f179.google.com with SMTP id 5614622812f47-3e600ae1664so875370b6e.2 for <70724@debbugs.gnu.org>; Thu, 21 Nov 2024 15:38:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1732232221; x=1732837021; darn=debbugs.gnu.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=44WuLjMigwbnCWOuz/kLh5iSKbDqD/FEC8xTP81igPc=; b=KkZEtGJmGIDq/53cAe0RFPI8/DAmggrYowzvod7diLCWOZBKHujEajrckC9cNt6MaZ GWLL00aVPjDEgXpubRMQMsREY70j109Imon4pjOTANkKSwuDsvlC7Ls5jsxJWFFUSXXl mNC7GkaahgSkKQ3hgAMmF/DTCpTzNirXnKwwGUCZRisExWxAsvSsshU2G1tlIlKKjV29 VJHbB6u4d0CUr7Qb9X9jmZ6N85j/wXxu6zDq96uVPPIg2z9+ftN+gWlRPc6fBq8b7/gu kY8OianU0hksfV8cL2jS9jS/27RukW72xueaGsjDnreCDnyfgBZolqgjl9SfBdEUSqRi ANbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732232221; x=1732837021; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=44WuLjMigwbnCWOuz/kLh5iSKbDqD/FEC8xTP81igPc=; b=Gqc8g6nyb5R8f5Em5jJdOzknRANqyPCI/SDrbsUEr70SH5TI34qBC0ygm7vS5idHRK ctGCOfMUKz3OgTR8//nsnSF5sCaW2ulWNjpZaDA8A+6JyG+zet70vQ08RYyR0q+jwijE advumnYwwF/nGxLVu2biGWf32j5iRkb68jA51xTWsxd8DC/r+LjWc2xW79mmGxltadSk 5fQcnDzzKowoKcIhRFbRInSxLY7uBOZ5MjD1Gp7aX2A/NOl9ZwBws7Gng0zH+IBz2KAG SAKEiZS9MPynTci+nVirlhhZdV8ONMo7KzQV9eG05DSmZzXnT2AZ3KulJA18pgKu6bwc je9g== X-Forwarded-Encrypted: i=1; AJvYcCXxIbqypaO2OfRxQwTo80jkNyfOMjb0xV5GwFnrTNmIFqK7E6CpTrjspIB8AXSm0mOMm2JpTA==@debbugs.gnu.org X-Gm-Message-State: AOJu0YyuJ+DQF+alUsyK38JcLM4Um7bZcuSVYeD+dQo4Sbr2sqKf69oG JnqVlgnYqgVc31ANzYVjzBs6ZLCDkhK+hHmpvt2q2bYXCly+VJBOMPfatrpgdl9qEDm+5Goqnn8 0fKC//u0HoQqzxpzSPCKSvRRPAaA= X-Gm-Gg: ASbGnctn2fTy6zPSHpjO3UHDihjCcRcTM60Ki4Xe/si7UVjQDTYxcGZFcOWMKS1jeyW 6StsSww1owutYzS/QWyFAS5exyaxdIg== X-Google-Smtp-Source: AGHT+IE/HId83yWCdp9iPV9pClxrSjKHAZYWIV188wpTeLjJv+nwzoMPnDL6282xKCSV1dCz/ta99vsyQaQSRIBGacc= X-Received: by 2002:a05:6808:ec6:b0:3e5:f656:dd19 with SMTP id 5614622812f47-3e91582c839mr1062373b6e.19.1732232221438; Thu, 21 Nov 2024 15:37:01 -0800 (PST) In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:295759 Archived-At: --0000000000003a3d18062774becc Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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=C3=A3o On Thu, Nov 21, 2024, 20:51 Spencer Baugh wrote: > Jo=C3=A3o T=C3=A1vora 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 ((keyword= p > (car contact)) contact) ((integerp (car (cdr contact))) (setq server-info > (list (format "%s:%s" ... ...))) (list ':process #'(lambda nil ...))) ((a= nd > (stringp (car contact)) (cl-find-if #'... contact)) (setq server-info (li= st > "")) (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 param= s) > (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)) (le= t* > ((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 (con= sp > --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--))) (nrevers= e > --cl-var--)) v)) (run-hook-with-args 'eglot-server-initialized-hook serve= r) > (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=3Dno -o > ControlPath=3Dnone")) (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(#) > (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-reconnectin= g, > last one didn't last long."))) > eglot--on-shutdown(#) > funcall(eglot--on-shutdown #= ) > (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 wit= h > status %s" (process-exit-status proc)) (delete-process proc) (let* ((p (a= nd > 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 tim= er > (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--continuation= s > 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 tim= er > (progn ...))))))))))) (jsonrpc--deferred-actions connection)) (process-pu= t > 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 (n= ot > (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(# (dune-add-disable-file-watcher-rpc/(tuareg-mode))> "exited abnormally wit= h > code 1\n") > --0000000000003a3d18062774becc Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
So, the error is explanatory, no??=C2=A0= As far as I can tell your original=C2=A0
patch also= signalled an error, and that error happened in the sentinel.

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

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

Jo=C3=A3o



On Thu, Nov 21= , 2024, 20:51 Spencer Baugh <sbaugh@janestreet.com> wrote:
Jo=C3=A3o T=C3=A1vora <joaotavora= @gmail.com> writes:

> Explain your scenario, please.=C2=A0 And note that if you take the rug= from
> underneath Eglot it will error, period.=C2=A0 That's by design.=C2= =A0 =C2=A0I'm not
> willing to contort the code to do=C2=A0 anything more than provide a > more or less understandable error message for such (relatively rare) > rug pulling.=C2=A0 IOW sentinels erroring is part of Emacs life and no= t a
> bug in itself,=C2=A0 it's the error message that I'm willing t= o help ensure is
> clear.

I use (the equivalent of) git worktrees to have one repo checkout per
branch that I'm working on.=C2=A0 As I finish work on a branch, I delet= e the
worktree with a shell command outside of Emacs.=C2=A0 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<= br> > same recipe in the beginning of the bug report.
>

Sure, here's the backtrace with the patch in your last email.=C2=A0 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/h= ome/sbaugh/workspaces/fe-880764/+share+/' is gone!")
=C2=A0 signal(error ("[eglot] Project at `/usr/local/home/sbaugh/works= paces/fe-880764/+share+/' is gone!"))
=C2=A0 error("[eglot] %s" "Project at `/usr/local/home/sbaug= h/workspaces/fe-880764/+share+/' is gone!")
=C2=A0 eglot--error("Project at `%s' is gone!" "/usr/loc= al/home/sbaugh/workspaces/fe-880764/+share+/")
=C2=A0 (if (file-exists-p default-directory) (project-name project) (eglot-= -error "Project at `%s' is gone!" default-directory))
=C2=A0 (let* ((default-directory (project-root project)) (nickname (if (fil= e-exists-p default-directory) (project-name project) (eglot--error "Pr= oject at `%s' is gone!" default-directory))) (readable-name (forma= t "EGLOT (%s/%s)" nickname managed-modes)) server-info (contact (= if (functionp contact) (funcall contact) contact)) (initargs (cond ((keywor= dp (car contact)) contact) ((integerp (car (cdr contact))) (setq server-inf= o (list (format "%s:%s" ... ...))) (list ':process #'(lam= bda 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 &= #39;...))) ((stringp (car contact)) (let* ((probe ...) (more-initargs ...) = (contact ...)) (cons ':process (cons ... more-initargs)))))) (spread #&= #39;(lambda (fn) #'(lambda (server method params) (let ... ...)))) (ser= ver (apply #'make-instance class :name readable-name :events-buffer-con= fig eglot-events-buffer-config :notification-dispatcher (funcall spread #&#= 39;eglot-handle-notification) :request-dispatcher (funcall spread #'egl= ot-handle-request) :on-shutdown #'eglot--on-shutdown initargs)) (cancel= ed nil) (tag (make-symbol "connected-catch-tag"))) (if server-inf= o (progn (jsonrpc--debug server "Running language server: %s" (st= ring-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-- manag= ed-modes) (m nil) (--cl-var-- language-ids) (l nil) (--cl-var-- nil)) (whil= e (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-as= ync-request server :initialize ... :success-fn ... :timeout eglot-connect-t= imeout :error-fn ... :timeout-fn ...) (cond ... ...)))) (cond ((consp retva= l) (let* (...) (if ... ... ...))) ((null retval) (let nil (eglot--message &= quot;Waiting in background for server `%s'" ...) nil)) (t (let nil= server)))) (quit (jsonrpc-shutdown server) (setq canceled 'quit))) (se= tq tag nil)))
=C2=A0 eglot--connect((tuareg-mode) #s(jane-fe-project :workspace "/us= r/local/home/sbaugh/workspaces/fe-880764/+share+/" :vc (vc Hg "/u= sr/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&quo= t; "open! Core" "dev") (readable-name . "EGLOT (du= ne-add-disable-file-watcher-rpc/(tuareg-mode))") tramp-ssh-controlmast= er-options tramp-use-ssh-controlmaster-options) nil (let ((default-director= y default-directory) (tramp-use-ssh-controlmaster-options 'suppress) (t= ramp-ssh-controlmaster-options "-o ControlMaster=3Dno -o ControlPath= =3Dnone")) (make-process :name readable-name :command (setq server-inf= o (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"))
=C2=A0 eglot-reconnect(#<eglot-lsp-server eglot-lsp-server-18f8056>)<= br> =C2=A0 (cond ((eglot--shutdown-requested server) t) ((not (eglot--inhibit-a= utoreconnect server)) (eglot--warn "Reconnecting after unexpected serv= er exit.") (eglot-reconnect server)) ((timerp (eglot--inhibit-autoreco= nnect server)) (eglot--warn "Not auto-reconnecting, last one didn'= t last long.")))
=C2=A0 eglot--on-shutdown(#<eglot-lsp-server eglot-lsp-server-18f8056>= ;)
=C2=A0 funcall(eglot--on-shutdown #<eglot-lsp-server eglot-lsp-server-18= f8056>)
=C2=A0 (unwind-protect (mapc #'(lambda (jsonrpc-lambda-elem168) (apply = #'(lambda (_id _method _success-fn error-fn _timer) (funcall error-fn &= #39;(: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 (dele= te-process p) nil)) (funcall (jsonrpc--on-shutdown connection) connection))=
=C2=A0 (progn (save-current-buffer (set-buffer (jsonrpc-events-buffer conne= ction)) (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--continuati= ons connection)) (maphash #'(lambda (_ triplet) (progn (ignore (consp t= riplet)) (let* ((x919 (cdr-safe triplet))) (progn (ignore (consp x919)) (le= t* ((x920 (car-safe x919)) (x921 (cdr-safe x919))) (progn (ignore (consp x9= 21)) (let* ((x923 (cdr-safe x921))) (progn (ignore (null x923)) (let ((time= r x920)) (if timer (progn (cancel-timer timer)))))))))))) (jsonrpc--deferre= d-actions connection)) (process-put proc 'jsonrpc-sentinel-cleanup-star= ted t) (unwind-protect (mapc #'(lambda (jsonrpc-lambda-elem168) (apply = #'(lambda (_id _method _success-fn error-fn _timer) (funcall error-fn &= #39;(: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 (dele= te-process p) nil)) (funcall (jsonrpc--on-shutdown connection) connection))= )
=C2=A0 (if (not (process-live-p proc)) (progn (save-current-buffer (set-buf= fer (jsonrpc-events-buffer connection)) (let ((inhibit-read-only t)) (inser= t "\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-lambd= a-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 ...))))))))))) (j= sonrpc--deferred-actions connection)) (process-put proc 'jsonrpc-sentin= el-cleanup-started t) (unwind-protect (mapc #'(lambda (jsonrpc-lambda-e= lem168) (apply #'(lambda (_id _method _success-fn error-fn _timer) (fun= call error-fn '(:code -1 :message "Server died"))) jsonrpc-la= mbda-elem168)) (jsonrpc--continuations connection)) (jsonrpc--message "= ;Server exited with status %s" (process-exit-status proc)) (delete-pro= cess proc) (let* ((p (and t (slot-value connection '-autoport-inferior)= ))) (if p (delete-process p) nil)) (funcall (jsonrpc--on-shutdown connectio= n) connection))))
=C2=A0 (let ((connection (process-get proc 'jsonrpc-connection))) (json= rpc--debug connection "Connection state change: `%s'" change)= (if (not (process-live-p proc)) (progn (save-current-buffer (set-buffer (j= sonrpc-events-buffer connection)) (let ((inhibit-read-only t)) (insert &quo= t;\n----------b---y---e---b---y---e----------\n"))) (mapc #'(lambd= a (jsonrpc-lambda-elem167) (apply #'(lambda (_id _method _success-fn _e= rror-fn timer) (if timer (progn (cancel-timer timer)))) jsonrpc-lambda-elem= 167)) (jsonrpc--continuations connection)) (maphash #'(lambda (_ triple= t) (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 (ignor= e (null x923)) (let (...) (if timer ...)))))))))) (jsonrpc--deferred-action= s connection)) (process-put proc 'jsonrpc-sentinel-cleanup-started t) (= unwind-protect (mapc #'(lambda (jsonrpc-lambda-elem168) (apply #'(l= ambda (_id _method _success-fn error-fn _timer) (funcall error-fn '(:co= de -1 :message "Server died"))) jsonrpc-lambda-elem168)) (jsonrpc= --continuations connection)) (jsonrpc--message "Server exited with sta= tus %s" (process-exit-status proc)) (delete-process proc) (let* ((p (a= nd t (slot-value connection '-autoport-inferior)))) (if p (delete-proce= ss p) nil)) (funcall (jsonrpc--on-shutdown connection) connection)))))
=C2=A0 jsonrpc--process-sentinel(#<process EGLOT (dune-add-disable-file-= watcher-rpc/(tuareg-mode))> "exited abnormally with code 1\n")=
--0000000000003a3d18062774becc--