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

Error on workspace/configuration request from Julia language server #340

Closed
non-Jedi opened this issue Nov 5, 2019 · 5 comments
Closed
Labels

Comments

@non-Jedi
Copy link

non-Jedi commented Nov 5, 2019

Since julia-vscode/LanguageServer.jl#374, the Julia language server sends a request that looks like:

server-request (id:-100) Tue Nov  5 15:16:06 2019:
(:method "workspace/configuration" :id -100 :params
         (:items
          [(:scopeUri nil :section "julia.format.indent")
           (:scopeUri nil :section "julia.format.indents")
           (:scopeUri nil :section "julia.format.ops")
           (:scopeUri nil :section "julia.format.tuples")
           (:scopeUri nil :section "julia.format.curly")
           (:scopeUri nil :section "julia.format.calls")
           (:scopeUri nil :section "julia.format.iterOps")
           (:scopeUri nil :section "julia.format.comments")
           (:scopeUri nil :section "julia.format.docs")
           (:scopeUri nil :section "julia.format.lineends")])
         :jsonrpc "2.0")

To which eglot responds with:

client-reply (id:-100) ERROR Tue Nov  5 15:16:06 2019:
(:jsonrpc "2.0" :id -100 :result nil :error
          (:code -32603 :message "Internal error"))

This in turn crashes the Julia language server since it expects the result field to be an array. Reading the specification, I think it's correct to expect that.

On the Julia side, I think sending the scopeUri fields as null is incorrect, and I'm assuming this is what triggers the error on the eglot side.

I think the actionable thing on the eglot side is to always send back a correctly formatted reply even for invalid requests?

Backtrace:

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  expand-file-name(nil)
  locate-dominating-file(nil dir-locals--all-files)
  dir-locals-find-file("")
  hack-dir-local-variables()
  hack-dir-local-variables-non-file-buffer()
  #f(compiled-function () #<bytecode 0x16e0af1>)()
  eglot--call-with-interface((ConfigurationItem nil (:scopeUri :section)) (:scopeUri nil :section "julia.format.indent") #f(compiled-function () #<bytecode 0x16e0af1>))
  #f(compiled-function (jsonrpc-lambda-elem14) #<bytecode 0x16e0aad>)((:scopeUri nil :section "julia.format.indent"))
  mapcar(#f(compiled-function (jsonrpc-lambda-elem14) #<bytecode 0x16e0aad>) [(:scopeUri nil :section "julia.format.indent") (:scopeUri nil :section "julia.format.indents") (:scopeUri nil :section "julia.format.ops") (:scopeUri nil :section "julia.format.tuples") (:scopeUri nil :section "julia.format.curly") (:scopeUri nil :section "julia.format.calls") (:scopeUri nil :section "julia.format.iterOps") (:scopeUri nil :section "julia.format.comments") (:scopeUri nil :section "julia.format.docs") (:scopeUri nil :section "julia.format.lineends")])
  #f(compiled-function (arg1 arg2 &rest rest) "Handle server request workspace/configuration." #<bytecode 0x167a931>)(#<eglot-lsp-server eglot-lsp-server> workspace/configuration :items [(:scopeUri nil :section "julia.format.indent") (:scopeUri nil :section "julia.format.indents") (:scopeUri nil :section "julia.format.ops") (:scopeUri nil :section "julia.format.tuples") (:scopeUri nil :section "julia.format.curly") (:scopeUri nil :section "julia.format.calls") (:scopeUri nil :section "julia.format.iterOps") (:scopeUri nil :section "julia.format.comments") (:scopeUri nil :section "julia.format.docs") (:scopeUri nil :section "julia.format.lineends")])
  apply(#f(compiled-function (arg1 arg2 &rest rest) "Handle server request workspace/configuration." #<bytecode 0x167a931>) #<eglot-lsp-server eglot-lsp-server> workspace/configuration (:items [(:scopeUri nil :section "julia.format.indent") (:scopeUri nil :section "julia.format.indents") (:scopeUri nil :section "julia.format.ops") (:scopeUri nil :section "julia.format.tuples") (:scopeUri nil :section "julia.format.curly") (:scopeUri nil :section "julia.format.calls") (:scopeUri nil :section "julia.format.iterOps") (:scopeUri nil :section "julia.format.comments") (:scopeUri nil :section "julia.format.docs") (:scopeUri nil :section "julia.format.lineends")]))
  eglot-handle-request(#<eglot-lsp-server eglot-lsp-server> workspace/configuration :items [(:scopeUri nil :section "julia.format.indent") (:scopeUri nil :section "julia.format.indents") (:scopeUri nil :section "julia.format.ops") (:scopeUri nil :section "julia.format.tuples") (:scopeUri nil :section "julia.format.curly") (:scopeUri nil :section "julia.format.calls") (:scopeUri nil :section "julia.format.iterOps") (:scopeUri nil :section "julia.format.comments") (:scopeUri nil :section "julia.format.docs") (:scopeUri nil :section "julia.format.lineends")])
  apply(eglot-handle-request #<eglot-lsp-server eglot-lsp-server> workspace/configuration (:items [(:scopeUri nil :section "julia.format.indent") (:scopeUri nil :section "julia.format.indents") (:scopeUri nil :section "julia.format.ops") (:scopeUri nil :section "julia.format.tuples") (:scopeUri nil :section "julia.format.curly") (:scopeUri nil :section "julia.format.calls") (:scopeUri nil :section "julia.format.iterOps") (:scopeUri nil :section "julia.format.comments") (:scopeUri nil :section "julia.format.docs") (:scopeUri nil :section "julia.format.lineends")]))
  #f(compiled-function (server method params) #<bytecode 0x1697cf1>)(#<eglot-lsp-server eglot-lsp-server> workspace/configuration (:items [(:scopeUri nil :section "julia.format.indent") (:scopeUri nil :section "julia.format.indents") (:scopeUri nil :section "julia.format.ops") (:scopeUri nil :section "julia.format.tuples") (:scopeUri nil :section "julia.format.curly") (:scopeUri nil :section "julia.format.calls") (:scopeUri nil :section "julia.format.iterOps") (:scopeUri nil :section "julia.format.comments") (:scopeUri nil :section "julia.format.docs") (:scopeUri nil :section "julia.format.lineends")]))
  jsonrpc-connection-receive(#<eglot-lsp-server eglot-lsp-server> (:method "workspace/configuration" :id -100 :params (:items [(:scopeUri nil :section "julia.format.indent") (:scopeUri nil :section "julia.format.indents") (:scopeUri nil :section "julia.format.ops") (:scopeUri nil :section "julia.format.tuples") (:scopeUri nil :section "julia.format.curly") (:scopeUri nil :section "julia.format.calls") (:scopeUri nil :section "julia.format.iterOps") (:scopeUri nil :section "julia.format.comments") (:scopeUri nil :section "julia.format.docs") (:scopeUri nil :section "julia.format.lineends")]) :jsonrpc "2.0"))
  jsonrpc--process-filter(#<process EGLOT (tmp/julia-mode)> "Content-Length: 582\015\n\015\n{\"method\":\"workspace/configuration\",\"id\":-100,\"params\":{\"items\":[{\"scopeUri\":null,\"section\":\"julia.format.indent\"},{\"scopeUri\":null,\"section\":\"julia.format.indents\"},{\"scopeUri\":null,\"section\":\"julia.format.ops\"},{\"scopeUri\":null,\"section\":\"julia.format.tuples\"},{\"scopeUri\":null,\"section\":\"julia.format.curly\"},{\"scopeUri\":null,\"section\":\"julia.format.calls\"},{\"scopeUri\":null,\"section\":\"julia.format.iterOps\"},{\"scopeUri\":null,\"section\":\"julia.format.comments\"},{\"scopeUri\":null,\"section\":\"julia.format.docs\"},{\"scopeUri\":null,\"section\":\"julia.format.lineends\"}]},\"jsonrpc\":\"2.0\"}")
@nemethf
Copy link
Collaborator

nemethf commented Nov 5, 2019

I think the client reply above is not in line with the specification, but because of different reasons. The specification says:

interface ResponseMessage extends Message {
...
/**
 * The result of a request. This member is REQUIRED on success.
 * This member MUST NOT exist if there was an error invoking the method.
 */
result?: string | number | boolean | object | null;

So the result part should be omitted.

But having an "Internal error" is a problem of its own.

@joaotavora joaotavora added the bug label Nov 5, 2019
@joaotavora
Copy link
Owner

There are two bugs here.

  1. A jsonrpc.el bug.
  2. An eglot bug, but maybe somewhere else in Emacs.

The first is my doing, but seems easy to fix. The second I have to understand a bit better.

@joaotavora
Copy link
Owner

A jsonrpc.el bug.

I've fixed this in jsonrpc.el 1.0.8 which should appear tomorrow on GNU Elpa. This is the path, if your're interested:

commit a8dbb7cc865f227a39708df3fe8d24e6f52b6e28
Author: João Távora <[email protected]>
Date:   Tue Nov 5 23:37:30 2019 +0000

    Follow JSONRPC spec by not sending :result field on errors
    
    Also don't send :error field on non-errors.
    
    * lisp/jsonrpc.el (jsonrpc--reply): Don't send :result and :error
    if none supplied.
    (Version): Bump to 1.0.8

diff --git a/lisp/jsonrpc.el b/lisp/jsonrpc.el
index 41cd84627b..abab445fe5 100644
--- a/lisp/jsonrpc.el
+++ b/lisp/jsonrpc.el
@@ -5,7 +5,7 @@
 ;; Author: João Távora <[email protected]>
 ;; Keywords: processes, languages, extensions
 ;; Package-Requires: ((emacs "25.2"))
-;; Version: 1.0.7
+;; Version: 1.0.8
 
 ;; This is an Elpa :core package.  Don't use functionality that is not
 ;; compatible with Emacs 25.2.
@@ -460,9 +460,13 @@ jsonrpc--json-encode
                                          (json-null nil))
                                      (json-encode object)))))
 
-(cl-defun jsonrpc--reply (connection id &key (result nil result-supplied-p) error)
+(cl-defun jsonrpc--reply
+    (connection id &key (result nil result-supplied-p) (error nil error-supplied-p))
   "Reply to CONNECTION's request ID with RESULT or ERROR."
-  (jsonrpc-connection-send connection :id id :result result :error error))
+  (apply #'jsonrpc-connection-send connection
+         `(:id ,id
+               ,@(and result-supplied-p `(:result ,result))
+               ,@(and error-supplied-p `(:error ,error)))))
 
 (defun jsonrpc--call-deferred (connection)
   "Call CONNECTION's deferred actions, who may again defer themselves."

joaotavora added a commit that referenced this issue Nov 5, 2019
* eglot.el (eglot-handle-request): Don't choke on nil scopeUri.
@joaotavora
Copy link
Owner

Regarding the second bug, can you try the commit I just pushed?

@non-Jedi
Copy link
Author

non-Jedi commented Nov 6, 2019

Using 21f8d40, things seem to work without breaking:

server-request (id:-100) Wed Nov  6 07:55:09 2019:
(:method "workspace/configuration" :id -100 :params
         (:items
          [(:scopeUri nil :section "julia.format.indent")
           (:scopeUri nil :section "julia.format.indents")
           (:scopeUri nil :section "julia.format.ops")
           (:scopeUri nil :section "julia.format.tuples")
           (:scopeUri nil :section "julia.format.curly")
           (:scopeUri nil :section "julia.format.calls")
           (:scopeUri nil :section "julia.format.iterOps")
           (:scopeUri nil :section "julia.format.comments")
           (:scopeUri nil :section "julia.format.docs")
           (:scopeUri nil :section "julia.format.lineends")])
         :jsonrpc "2.0")

client-reply (id:-100) Wed Nov  6 07:55:09 2019:
(:jsonrpc "2.0" :id -100 :result
          [nil nil nil nil nil nil nil nil nil nil])

Thanks for fixing this. I appreciate your work on eglot and elsewhere in emacs.

xuchunyang pushed a commit to xuchunyang/eglot that referenced this issue Nov 16, 2019
…opeUri

* eglot.el (eglot-handle-request): Don't choke on nil scopeUri.
joaotavora referenced this issue Sep 17, 2022
Also tweak eglot-show-workspace-configuration a bit.

* README.md (Workspace configuration): Rework.

* eglot.el (eglot-show-workspace-configuration): Rework.
(eglot--workspace-configuration-plist): New helper.
bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 18, 2022
… no scopeUri

* eglot.el (eglot-handle-request): Don't choke on nil scopeUri.
bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 19, 2022
… no scopeUri

* eglot.el (eglot-handle-request): Don't choke on nil scopeUri.
bhankas pushed a commit to bhankas/emacs that referenced this issue Sep 19, 2022
* eglot.el (eglot-handle-request): Don't choke on nil scopeUri.

#340: joaotavora/eglot#340
jollaitbot pushed a commit to sailfishos-mirror/emacs that referenced this issue Oct 12, 2022
* eglot.el (eglot-handle-request): Don't choke on nil scopeUri.

GitHub-reference: fix joaotavora/eglot#340
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants