Eli Zaretskii writes: >> Cc: Stefan Monnier , Jason Rumney >> From: Spencer Baugh >> Date: Mon, 12 Feb 2024 17:10:34 -0500 >> >> Spencer Baugh writes: >> > 1. emacs -Q --fg-daemon=/nonexistent/dir/sock >> > 2. Emacs prints "Starting Emacs daemon." and sits in foreground. >> > 3. emacsclient -c -s /nonexistent/dir/sock >> > 4. emacsclient prints and exits: >> > emacsclient: can't find socket; have you started the server? >> > emacsclient: To start the server in Emacs, type "M-x server-start". >> > emacsclient: error accessing socket "/nonexistent/dir/sock" >> > >> > This is because in step 1, the server actually failed to start, but >> > Emacs did not log that at all. In fact, it's impossible to access the >> > Emacs started in 1 now, since it's not actually running a server and it >> > has no frames. >> >> Okay, I found what one might call the root cause, the following code and >> comment. Adding Stefan and Jason to CC as the original authors. >> >> /* The initial frame is a special non-displaying frame. It >> will be current in daemon mode when there are no frames >> to display, and in non-daemon mode before the real frame >> has finished initializing. If an error is thrown in the >> latter case while creating the frame, then the frame >> will never be displayed, so the safest thing to do is >> write to stderr and quit. In daemon mode, there are >> many other potential errors that do not prevent frames >> from being created, so continuing as normal is better in >> that case. */ >> || (!IS_DAEMON && FRAME_INITIAL_P (sf)) >> >> The comment is mostly sensible: we should exit while initializing, and >> shouldn't exit while in the steady state of daemon mode. > > Bug#1310 and bug#1836 are also relevant here. Indeed. >> However, it doesn't handle the case when Emacs is initializing *and* in >> daemon mode. In that case, an error will prevent frames from being >> created, just like in non-daemon mode. >> >> So this check really wants to be something more like: >> || ( IS_DAEMON && [something to check if Emacs is starting up]) >> || (!IS_DAEMON && FRAME_INITIAL_P (sf)) >> >> Not sure what [something to check if Emacs is starting up] should be >> though. > > after-init-time, I guess. But note that this still leaves a window > between where that is set non-nil and starting the server. Oh, actually there is a DAEMON_RUNNING define which is exactly what we want here. DAEMON_RUNNING just didn't exist at the time the check on IS_DAEMON was added. Patch using DAEMON_RUNNING attached. > Also, the patch for server-start which prevents it from erroring out > is still needed, because we do want to show the error message about > being unable to start the daemon. > > And this solution will still print error messages that are not > specific enough to be helpful. E.g., what do you do if you try > starting the daemon and see > > wrong-type-argument, stringp, nil > > and that's all? And that is even before we consider the use case > where stderr of the daemon is redirected to the great void, which > happens in some cases. > > So my vote is still for diagnosing the important places where a fatal > error could happen, and adding a clear diagnostic there. Yes, it is > more work. But the gain will be much higher. Agreed, I will also work on that as a separate change.