Skip to content

Misleading error messages after receiving invalid URI #3821

Open
@Andriamanitra

Description

@Andriamanitra

Is your enhancement request related to a problem? Please describe.

When a client send the server URI (most commonly textDocument.uri) with Unicode characters that are not properly percent-encoded there is no error, HLS keeps running but will not work as it should. The user will later receive confusing error messages such as this one when requesting textDocument/hover:

{"error":{"code":-32601,"message":"No plugin enabled for SMethod_TextDocumentHover, potentially available: ghcide-hover-and-symbols, explicit-fixity"},"id":1,"jsonrpc":"2.0"}

Describe the solution you'd like

I would like the language server to respond with an error when it receives an invalid request such as initializing / opening a document with an URI that contains characters that are not allowed according to RFC3986 (which the LSP specification says URIs should follow).

Additional context

I ran into this issue while implementing a LSP plugin for micro-editor. I forgot to percent-encode file URIs in outgoing communication which resulted in HLS (silently!) failing. I thought it was an error in my initializationParameters for a long time since all of the errors said "No plugin enabled" (and HLS also doesn't give any confirmation of whether you passed it invalid initializationParameters so it was a bit of guessing game).

Communication between the client and HLS when this issue happened
--> Content-Length: 433

{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":13986,"rootUri":"file:///home/mikko/koodit/µlsp","workspaceFolders":[{"name":"root","uri":"file:///home/mikko/koodit/µlsp"}],"initializationOptions":{"haskell":{"plugin":{"ghcide-hover-and-symbols":{"globalOn":true,"hoverOn":true}}}},"capabilities":{"textDocument":{"hover":{"contentFormat":["plaintext","markdown"]},"formatting":{"dynamicRegistration":false}}}}} 


<-- Content-Length: 1779

{"id":0,"jsonrpc":"2.0","result":{"capabilities":{"callHierarchyProvider":true,"codeActionProvider":{"resolveProvider":true},"codeLensProvider":{"resolveProvider":true,"workDoneProgress":false},"colorProvider":false,"completionProvider":{"resolveProvider":true,"triggerCharacters":["."]},"declarationProvider":false,"definitionProvider":true,"documentFormattingProvider":true,"documentHighlightProvider":true,"documentRangeFormattingProvider":true,"documentSymbolProvider":true,"executeCommandProvider":{"commands":["14011:retrie:retrieCommand","14011:retrie:retrieInlineThisCommand","14011:explicit-fields:codeActionResolve","14011:ghcide-extend-import-action:extendImport","14011:importLens:ImportLensCommand","14011:moduleName:updateModuleName","14011:splice:expandTHSpliceInplace","14011:hlint:codeActionResolve","14011:class:classplugin.codeaction","14011:class:classplugin.typelens","14011:ghcide-type-lenses:typesignature.add","14011:eval:evalCommand","14011:gadt:GADT.toGADT"]},"foldingRangeProvider":true,"hoverProvider":true,"implementationProvider":false,"referencesProvider":true,"renameProvider":true,"selectionRangeProvider":true,"semanticTokensProvider":{"legend":{"tokenModifiers":["declaration","definition","readonly","static","deprecated","abstract","async","modification","documentation","defaultLibrary"],"tokenTypes":["namespace","type","class","enum","interface","struct","typeParameter","parameter","variable","property","enumMember","event","function","method","macro","keyword","modifier","comment","string","number","regexp","operator","decorator"]}},"textDocumentSync":{"change":2,"openClose":true,"save":{}},"typeDefinitionProvider":true,"workspace":{"workspaceFolders":{"changeNotifications":true,"supported":true}},"workspaceSymbolProvider":true}}} 


--> Content-Length: 52

{"jsonrpc":"2.0","method":"initialized","params":{}} 


--> Content-Length: 202

{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///home/mikko/koodit/µlsp/hello.hs","languageId":"haskell","version":1,"text":"main = print \"Hello world!\"\n"}}} 


--> Content-Length: 167

{"jsonrpc":"2.0","id":1,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///home/mikko/koodit/µlsp/hello.hs"},"position":{"line":0,"character":8}}} 


<-- Content-Length: 174

{"error":{"code":-32601,"message":"No plugin enabled for SMethod_TextDocumentHover, potentially available: ghcide-hover-and-symbols, explicit-fixity"},"id":1,"jsonrpc":"2.0"} 
stderr output from haskell-language-server-wrapper --debug --lsp
No 'hie.yaml' found. Try to discover the project type!
Run entered for haskell-language-server-wrapper(haskell-language-server-wrapper) Version 2.3.0.0 x86_64 ghc-9.0.2
Current directory: /home/mikko/nvme_ssd/Koodit/µlsp
Operating system: linux
Arguments: ["--debug","--lsp"]
Cradle directory: /home/mikko/nvme_ssd/Koodit/µlsp
Cradle type: Default

Tool versions found on the $PATH
cabal:          3.10.1.0
stack:          Not found
ghc:            9.6.2


Consulting the cradle to get project GHC version...
2023-10-01T14:47:45.039470Z | Debug | executing command: ghc --numeric-version
Project GHC version: 9.6.2
haskell-language-server exe candidates: ["haskell-language-server-9.6.2","haskell-language-server"]
Launching haskell-language-server exe at:/home/mikko/.local/bin/haskell-language-server-9.6.2
2023-10-01T14:47:45.069781Z | Debug | executing command: ghc -v0 -package-env=- -ignore-dot-ghci -e Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)
2023-10-01T14:47:45.155095Z | Debug | executing command: ghc --print-libdir
2023-10-01T14:47:46.242208Z | Info | haskell-language-server version: 2.3.0.0 (GHC: 9.6.2) (PATH: /home/mikko/.local/share/ghcup/hls/2.3.0.0/lib/haskell-language-server-2.3.0.0/bin/haskell-language-server-9.6.2)
2023-10-01T14:47:46.242866Z | Info | Directory: /home/mikko/nvme_ssd/Koodit/µlsp
2023-10-01T14:47:46.243021Z | Info | Starting (haskell-language-server) LSP server...
  GhcideArguments {argsCommand = LSP, argsCwd = Nothing, argsShakeProfiling = Nothing, argsTesting = False, argsExamplePlugin = False, argsLogLevel = Debug, argsLogFile = Nothing, argsLogStderr = True, argsLogClient = False, argsThreads = 0, argsProjectGhcVersion = False}
  PluginIds: [ pragmas-suggest
             , pragmas-completion
             , retrie
             , ghcide-completions
             , alternateNumberFormat
             , ghcide-code-actions-bindings
             , explicit-fields
             , ghcide-hover-and-symbols
             , ghcide-code-actions-type-signatures
             , fourmolu
             , ghcide-extend-import-action
             , ghcide-code-actions-fill-holes
             , importLens
             , LSPRecorderCallback
             , cabal
             , qualifyImportedNames
             , moduleName
             , splice
             , stylish-haskell
             , changeTypeSignature
             , hlint
             , class
             , ormolu
             , callHierarchy
             , ghcide-type-lenses
             , codeRange
             , cabal-fmt
             , eval
             , rename
             , ghcide-code-actions-imports-exports
             , gadt
             , overloaded-record-dot
             , ghcide-core
             , explicit-fixity
             , pragmas-disable ]
2023-10-01T14:47:46.245229Z | Info | Logging heap statistics every 60.00s
 2023-10-01T14:47:46.262395Z | Info | Starting LSP server...
  If you are seeing this in a terminal, you probably should have run WITHOUT the --lsp option!
  PluginIds: [ pragmas-suggest
             , pragmas-completion
             , retrie
             , ghcide-completions
             , alternateNumberFormat
             , ghcide-code-actions-bindings
             , explicit-fields
             , ghcide-hover-and-symbols
             , ghcide-code-actions-type-signatures
             , fourmolu
             , ghcide-extend-import-action
             , ghcide-code-actions-fill-holes
             , importLens
             , LSPRecorderCallback
             , cabal
             , qualifyImportedNames
             , moduleName
             , splice
             , stylish-haskell
             , changeTypeSignature
             , hlint
             , class
             , ormolu
             , callHierarchy
             , ghcide-type-lenses
             , codeRange
             , cabal-fmt
             , eval
             , rename
             , ghcide-code-actions-imports-exports
             , gadt
             , overloaded-record-dot
             , ghcide-core
             , explicit-fixity
             , pragmas-disable ]
2023-10-01T14:47:46.262656Z | Info | Starting server
2023-10-01T14:47:46.263918Z | Info | Started LSP server in 0.00s
2023-10-01T14:47:46.268418Z | Debug | executing command: ghc --print-libdir
2023-10-01T14:47:46.305081Z | Debug | Setting initial dynflags...
2023-10-01T14:47:46.305197Z | Debug | shouldRunSubset: False
2023-10-01T14:47:46.305330Z | Debug | Initializing exports map from hiedb
2023-10-01T14:47:46.305672Z | Info | Registering IDE configuration: IdeConfiguration {workspaceFolders = fromList [NormalizedUri (-4500577356667336057) "file:///home/mikko/koodit/%C2%B5lsp"], clientSettings = hashed (Just (Object (fromList [("haskell",Object (fromList [("plugin",Object (fromList [("ghcide-hover-and-symbols",Object (fromList [("globalOn",Bool True),("hoverOn",Bool True)]))]))]))])))}
2023-10-01T14:47:46.307915Z | Debug | Done initializing exports map from hiedb. Size: 1
2023-10-01T14:47:46.307994Z | Debug | LSP: not requesting configuration since the client does not support workspace/configuration
2023-10-01T14:47:46.308077Z | Debug | Shake session initialized
2023-10-01T14:47:46.308097Z | Debug | VFS: opening file:///home/mikko/koodit/%C2%B5lsp/hello.hs
2023-10-01T14:47:46.308129Z | Debug | Warning: Client does not support watched files. Falling back to OS polling
2023-10-01T14:47:46.308290Z | Warning | No plugin enabled for "textDocument/didOpen"
2023-10-01T14:47:46.346831Z | Warning | No plugin enabled for "textDocument/hover"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions