Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Panics when used with Sublime Text 3 LSP #1038

Closed
kornelski opened this issue Sep 4, 2018 · 7 comments
Closed

Panics when used with Sublime Text 3 LSP #1038

kornelski opened this issue Sep 4, 2018 · 7 comments

Comments

@kornelski
Copy link

When used in Sublime, rls occasionally panics:

server: DEBUG 2018-09-04T19:28:59Z: rls::server::message: error when parsing as request: invalid type: map, expected unit
server: ERROR 2018-09-04T19:28:59Z: rls::server: dispatch error, Error { code: InvalidParams, message: "invalid type: map, expected unit", data: None }
server: thread 'main' panicked at 'orphaned concurrent job', tools/rls/src/concurrency.rs:82:9

sublimelsp/LSP#399

rls-preview 0.130.0-beta (920a391 2018-08-03)

There are two problems here:

  1. It panics.

  2. There isn't much information about the panic, so it's hard to tell whether that's RLS's problem, or LSP's problem.

@alexheretic
Copy link
Member

alexheretic commented Sep 4, 2018

This error means rls is trying to read request text sent from the lsp client but part of it is in an incorrect format. Either the client is sending a message that doesn't match the protocol, or the languageserver-types lib rls uses isn't handling the protocol fully.

To figure that out the actual json message would be very helpful. Rls logs it with trace logging strings starting with Read message & Parsed message . Can you turn on trace logging and post the offending json?

You may also be able to get the json clientside.

@kornelski
Copy link
Author

kornelski commented Sep 5, 2018

I've wrapped rls in a shell script that sets RUST_LOG=rls=debug, but this output still gets captured by Sublime, and it's already overwhelmingly noisy in the Sublime console.

Is there a more specific env var I can set to capture just these messages? Or can rls log to a file instead?

It may also be helpful if you use warn/error level for logging the message that failed to parse before panicking.

@alexheretic
Copy link
Member

env_logger can be module specific, I'd still just bosh stderr to a file RUST_LOG=rls::server=trace rls 2> rls.stderr

It may also be helpful if you use warn/error level for logging the message that failed to parse before panicking.

I agree.

@Xanewok
Copy link
Member

Xanewok commented Sep 5, 2018

This reminds me of gluon-lang/lsp-types#46. I thought it was long gone?

The module log is a lot cleaner; sometimes to get only RLS logs I used the RUST_LOG=rls=trace,rls_analysis=error to ignore the rls_analysis errors (there's a lot of them!).

@kornelski
Copy link
Author

With trace that's what I've got:

server: TRACE 2018-09-05T11:57:00Z: rls::server::io: reading: 63 bytes
server: TRACE 2018-09-05T11:57:00Z: rls::server: Read message `{"jsonrpc": "2.0", "id": 2, "method": "shutdown", "params": {}}`
server: TRACE 2018-09-05T11:57:00Z: rls::server: Parsed message `RawMessage { method: "shutdown", id: Num(2), params: Object({}) }`
server: TRACE 2018-09-05T11:57:00Z: rls::server: Handling `shutdown`
server: DEBUG 2018-09-05T11:57:00Z: rls::server::message: error when parsing as request: invalid type: map, expected unit
server: ERROR 2018-09-05T11:57:00Z: rls::server: dispatch error, Error { code: InvalidParams, message: "invalid type: map, expected unit", data: None }
server: TRACE 2018-09-05T11:57:00Z: rls::server::io: response: "Content-Length: 93\r\n\r\n{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32602,\"message\":\"invalid type: map, expected unit\"},\"id\":2}"
server: thread 'main' panicked at 'orphaned concurrent job', tools/rls/src/concurrency.rs:82:9

@alexheretic
Copy link
Member

alexheretic commented Sep 5, 2018

Thanks. It's a very tedious issue. The shutdown json includes an empty object as params, whereas the spec says void type ie undefined/null.

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "shutdown",
  "params": {}
}

Seems like the client library explicitly behaves this way.

# client library `Request`

def to_payload(self, id) -> dict:
    r = OrderedDict()  # type: OrderedDict[str, Any]
    r["jsonrpc"] = "2.0"
    r["id"] = id
    r["method"] = self.method
    if self.params is not None:
        r["params"] = self.params
    else:
        r["params"] = dict()
    return r

To resolve either or both

@alexheretic
Copy link
Member

Actually looking more closely, the deserialise logic is in rls, so maybe we can be more permissive here.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants