Skip to content
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

cider-jack-in throws Wrong type argument: stringp, nil when invoked from TRAMP ssh-buffer #3541

Closed
adrech opened this issue Oct 18, 2023 · 5 comments · Fixed by #3544
Closed

Comments

@adrech
Copy link
Contributor

adrech commented Oct 18, 2023

Expected behavior

In a tramp buffer connected to my rasperry pi via ssh, cider-jack-in creates a remote repl and connects to it.

Actual behaviour

cider-jack-in creates a remote repl and throws on connect:
"error in process filter: Wrong type argument: stringp, nil"

Steps

find-file /ssh:****@pi.local:~/hello/deps.edn [containing only "{}"]
M-x cider-jack-in

[nREPL] Starting server via clojure -Sdeps \{\:deps\ \{nrepl/nrepl\ \{\:mvn/version\ \"1.0.0\"\}\ cider/cider-nrepl\ \{\:mvn/version\ \"0.40.0\"\}\}\ \:aliases\ \{\:cider/nrepl\ \{\:main-opts\ \[\"-m\"\ \"nrepl.cmdline\"\ \"--middleware\"\ \"\[cider.nrepl/cider-middleware\]\"\]\}\}\} -M:cider/nrepl
[nREPL] server started on 40699
...
[nREPL] Falling back to SSH tunneled connection ...
[nREPL] Establishing SSH tunneled connection to pi.local:40699 ...
error in process filter: Wrong type argument: stringp, nil

Environment & Version Information

GNU Emacs 29.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.37, cairo version 1.16.0)
CIDER 1.8.3-snapshot, nREPL 1.0.0
Clojure 1.11.1, Java 17.0.8

Likely Reason & Attempted Solutions

The problem is that nrepl--ssh-tunnel-connect tries to string-match on (buffer-file-name) - which is nil, because the current execution context is the nrepl buffer:

;; (current-buffer) in edebug
#<buffer *nrepl-server hello:localhost*<13>>

Is this expected / did something change since this feature was introduced (#3264)?

To confirm, I changed this in nrepl--ssh-tunnel-connect:

(defun nrepl--ssh-tunnel-connect (host port)
  "Connect to a remote machine identified by HOST and PORT through SSH tunnel."
  (message "[nREPL] Establishing SSH tunneled connection to %s:%s ..." host port)
- (let* ((current-buf (buffer-file-name))
+ (let* ((current-buf (buffer-file-name (window-buffer (selected-window))))
         (tramp-file-regexp "/ssh:\\(.+@\\)?\\(.+?\\)\\(:\\|#\\).+")
         (remote-dir (cond
                      ;; If current buffer is a TRAMP buffer and its host is
                      ;; the same as HOST, reuse its connection parameters for
                      ;; SSH tunnel.
                      ((and (string-match tramp-file-regexp current-buf)
                            (string= host (match-string 2 current-buf))) current-buf)
                            ...

... which works, but only if one doesn't switch windows while cider is booting up.

A less flaky approach would be to pass down the buffer from which cider-jack-in was invoked.
This is what I'm doing now, but it's a lot of change in a lot of places and feels wrong:
master...adrech:cider:fix-ssh-jack-in

Originally posted by @adrech in #3303 (comment)

@vemv
Copy link
Member

vemv commented Oct 18, 2023

Thanks much for the accurate report and analysis.

We may use your branch, perhaps simplifying it by using a global variable or dynamic scope?

(But passing args is also OK, given that we intend to support concurrent repls)

I'll look into it.

@vemv vemv changed the title cider-jack-in throws "Wrong type argument: stringp, nil" when invoked from tramp ssh-buffer cider-jack-in throws Wrong type argument: stringp, nil when invoked from TRAMP ssh-buffer Oct 18, 2023
@adrech
Copy link
Contributor Author

adrech commented Oct 18, 2023

I thought about using a global at first, but wasn't sure how to handle situations were multiple connections are started in succession and might not finish in order.
This is my first deeper look into cider and my emacs-fu is quite basic... I'm intrigued how this would be solved with dynamic scope? Haven't made use of it yet.

Edit: Best case scenario would be not needing any of this. From #3264 I'd assume that it worked before and the bug is coming from something else that changed the current-buffer to the nrepl one in that context.

@vemv
Copy link
Member

vemv commented Oct 18, 2023

Checking out the issue, your branch, etc carefully, I'd say that your branch is the best approach as-is.

A PR that was verified to work would be most welcome.

Please make sure that the linting is passing in advance (use our Makefile for that).

Thanks - V

@adrech
Copy link
Contributor Author

adrech commented Oct 18, 2023

Alright, will do. I'll look into how to write proper tests for this tomorrow.
Are there contributor guidelines that I missed somehow [apart from the linting], or should I just follow the conventions I find in the source?

@vemv
Copy link
Member

vemv commented Oct 18, 2023

We don't have a lot of integration tests so adding the changes would suffice.

Simply indicate how to QA this, preferrably using https://github.com/clojure-emacs/cider/tree/master/dev/tramp-sample-project which has a readme / makefile.

adrech added a commit to adrech/cider that referenced this issue Oct 19, 2023
Calling cider-jack-in from a tramp buffer on a ssh-remote would throw:
"error in process filter: Wrong type argument: stringp, nil"

This happened because nrepl--ssh-tunnel-connect is trying to
string-match on (buffer-file-name) which returns nil, because the
execution context is the nrepl buffer.

To work around this, we pass down the buffer from which cider-jack-in
was called.

Considerations:

- This should be reverted if the cause of this feature breaking is
  found and fixable. It seemed to have worked before,
  see: clojure-emacs#3264

- In nrepl-client.el the param name "jack-in-buffer" seems a bit too
  specific. But, as long as this workaround is its only usecase, I
  consider it reasonable for discoverability.

- This should be refactored as soon as there's a more general way to convey
  contextual information to lower level functions.

Fixes:
clojure-emacs#3541
clojure-emacs#3303 (partially)
adrech added a commit to adrech/cider that referenced this issue Oct 19, 2023
Calling cider-jack-in from a tramp buffer on a ssh-remote would throw:
"error in process filter: Wrong type argument: stringp, nil"

This happened because nrepl--ssh-tunnel-connect is trying to
string-match on (buffer-file-name) which returns nil, because the
execution context is the nrepl buffer.

To work around this, we pass down the buffer from which cider-jack-in
was called.

Considerations:

- This should be reverted if the cause of this feature breaking is
  found and fixable. It seemed to have worked before,
  see: clojure-emacs#3264

- In nrepl-client.el the param name "jack-in-buffer" seems a bit too
  specific. But, as long as this workaround is its only usecase, I
  consider it reasonable for discoverability.

- This should be refactored as soon as there's a more general way to convey
  contextual information to lower level functions.

Fixes:
clojure-emacs#3541
clojure-emacs#3303 (partially)
adrech added a commit to adrech/cider that referenced this issue Oct 29, 2023
Calling cider-jack-in from a tramp buffer on a ssh-remote would throw:
"error in process filter: Wrong type argument: stringp, nil"

This happens because nrepl--ssh-tunnel-connect is trying to infer the
hostname from the current filename: It string-matches
on (buffer-file-name) which returns nil in
the *cider-uninitialized-repl* buffer.

For the jack-in use-case, the local var nrepl-project-dir will
always be bound when connecting the client, so we can use
it as a fallback.

Fixes:
clojure-emacs#3541
clojure-emacs#3303 (partially)
adrech added a commit to adrech/cider that referenced this issue Oct 29, 2023
Calling cider-jack-in from a tramp buffer on a ssh-remote would throw:
"error in process filter: Wrong type argument: stringp, nil"

This happens because nrepl--ssh-tunnel-connect is trying to infer the
hostname from the current filename: It string-matches
on (buffer-file-name) which returns nil in
the *cider-uninitialized-repl* buffer.

For the jack-in use-case, the local var nrepl-project-dir will
always be bound when connecting the client, so we can use
it as a fallback.

Fixes:
clojure-emacs#3541
clojure-emacs#3303 (partially)
adrech added a commit to adrech/cider that referenced this issue Oct 29, 2023
Calling cider-jack-in from a tramp buffer on a ssh-remote would throw:
"error in process filter: Wrong type argument: stringp, nil"

This happens because nrepl--ssh-tunnel-connect is trying to infer the
hostname from the current filename: It string-matches
on (buffer-file-name) which returns nil in
the *cider-uninitialized-repl* buffer.

For the jack-in use-case, the local var nrepl-project-dir will
always be bound when connecting the client, so we can use
it as a fallback.

Fixes:
clojure-emacs#3541
clojure-emacs#3303 (partially)
adrech added a commit to adrech/cider that referenced this issue Oct 29, 2023
Calling cider-jack-in from a tramp buffer on a ssh-remote would throw:
"error in process filter: Wrong type argument: stringp, nil"

This happens because nrepl--ssh-tunnel-connect is trying to infer the
hostname from the current filename: It string-matches
on (buffer-file-name) which returns nil in
the *cider-uninitialized-repl* buffer.

For the jack-in use-case, the local var nrepl-project-dir will
always be bound when connecting the client, so we can use
it as a fallback.

Fixes:
clojure-emacs#3541
clojure-emacs#3303 (partially)
adrech added a commit to adrech/cider that referenced this issue Oct 29, 2023
Calling cider-jack-in from a tramp buffer on a ssh-remote would throw:
"error in process filter: Wrong type argument: stringp, nil"

This happens because nrepl--ssh-tunnel-connect is trying to infer the
hostname from the current filename: It string-matches
on (buffer-file-name) which returns nil in
the *cider-uninitialized-repl* buffer.

For the jack-in use-case, the local var nrepl-project-dir will
always be bound when connecting the client, so we can use
it as a fallback.

Fixes:
clojure-emacs#3541
clojure-emacs#3303 (partially)
adrech added a commit to adrech/cider that referenced this issue Oct 30, 2023
Calling cider-jack-in from a tramp buffer on a ssh-remote would throw:
"error in process filter: Wrong type argument: stringp, nil"

This happens because nrepl--ssh-tunnel-connect is trying to infer the
hostname from the current filename: It string-matches
on (buffer-file-name) which returns nil in
the *cider-uninitialized-repl* buffer.

For the jack-in use-case, the local var nrepl-project-dir will
always be bound when connecting the client, so we can use
it as a fallback.

Fixes:
clojure-emacs#3541
clojure-emacs#3303 (partially)
vemv pushed a commit that referenced this issue Oct 30, 2023
* tramp-sample-project: fix Lein not finding `java` after cider-jack-in

This is a workaround that can be removed when `PATH` is picked up
correctly when jacking in on the running remote.

Circumvents:

```
Tramp: Opening connection nrepl-server for root@localhost using sshx...done
[nREPL] Starting server via lein update-in :dependencies conj \[nrepl/nrepl\ \"1.0.0\"\] -- update-in :plugins conj \[cider/cider-nrepl\ \"0.40.0\"\] -- repl :headless :host localhost
error in process sentinel: let: Could not start nREPL server: /usr/local/bin/lein: line 224: type: java: not found
Leiningen couldn't find 'java' executable, which is required.
Please either set JAVA_CMD or put java (>=1.6) in your $PATH (/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin).
 ("exited abnormally with code 1")
```

* tramp-sample-project: add `cider-jack-in` method to README

* Fix `cider-jack-in` failing with SSH remotes

Calling cider-jack-in from a tramp buffer on a ssh-remote would throw:
"error in process filter: Wrong type argument: stringp, nil"

This happens because nrepl--ssh-tunnel-connect is trying to infer the
hostname from the current filename: It string-matches
on (buffer-file-name) which returns nil in
the *cider-uninitialized-repl* buffer.

For the jack-in use-case, the local var nrepl-project-dir will
always be bound when connecting the client, so we can use
it as a fallback.

Fixes #3541
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants