haskell / haskell/haskell-language-server

File prefixes cannot be matched if files are located in mapped drives over SMB on Windows

Open
#1,630 0 comments 0 reactions 0 assignees View on GitHub
os: windows type: bug
Dominant language
Haskell
Stars
3k
Forks
455
Avg merge
2d 19h
Merged PRs (30d)
11

Description

For example, if I have some source code files which are located on a [mapped drive over SMB on Windows](https://support.microsoft.com/en-us/windows/map-a-network-drive-in-windows-10-29ce55d1-34e3-a7e2-4801-131475f9557d):
```
H:\Path\to\Project\src\Main.hs
```
which is mapped to the network location:
```
\\smb.hostname.tld\Path\to\Project\src\Main.hs
```

In this case, if I opened the file through the mapped drive, the path known by the editor is the first one, but the path in the response from the language server is actually resolved to the second one, which makes the language server client unable to parse the response. The full error message is the following:

```
src\Main.hs:
1:1 error Multi Cradle: No prefixes matched ​cradle
pwd: H:\Path\to\Project
filepath: \\smb.hostname.tld\Path\to\Project\src\Main.hs
prefixes:
("src/Main.hs",Cabal {component = Just "Project:exe:Project"})
...
```

I had the same issue when I was using another language server like plug-in for sublime text: [SublimeHaskell](https://github.com/SublimeHaskell/SublimeHaskell), and I found out that it was cause by using the function [`canonicalizePath`](https://hackage.haskell.org/package/directory-1.3.6.1/docs/System-Directory.html#v:canonicalizePath) to resolve the path of source code files. After replacing all `canonicalizePath` function calls in that plug-in to `makeAbsolute`, which does not replace the mapped drive part with the full network location path, the issue was resolved. It seems that this language server also [uses the `canonicalizePath` function to resolve paths](https://github.com/haskell/haskell-language-server/search?q=canonicalizePath).

In fact, the documentation of the `canonicalizePath` function states that:
> Note: This function is a very big hammer. If you only need an absolute path, `makeAbsolute` is sufficient for removing dependence on the current working directory.

Therefore, is it possible to replace all `canonicalizePath` function calls to `makeAbsolute`, given that the `makeAbsolute` function is recommended and is interchangeable with `canonicalizePath`?

---

### Your environment
Output of `haskell-language-server --probe-tools` or `haskell-language-server-wrapper --probe-tools`:
```sh
haskell-language-server version: 1.0.0.0 (GHC: 8.10.4) (PATH: haskell-language-server-8.10.4.exe) (GIT hash: 4cd1cf934638881e52b3eba9f70157a4b799c0e9)
Tool versions found on the $PATH
cabal: 3.4.0.0
stack: Not found
ghc: 8.10.4
```
Which lsp-client do you use:
Sublime Text (Dev Channel, Build 4099)

Describe your project (alternative: link to the project):
Private project

### Steps to reproduce
1. Open source code on a mapped drive over SMB in the text editor
2. Let the language server client send requests to the language server

### Expected behaviour
The file path in the response from the language server is still the mapped path, so the file prefix can be matched.

### Actual behaviour
The file path in the response from the language server is resolved to the full network location path, and the file prefix cannot be matched.

### Include debug information

Debug output: (Note: As the project is private, all paths has been replaced with appropriate paths in the example. I have checked the output line by line, but it may still have some inconsistencies, apologize for that.)

```
Module "H:\Path\to\Project\a" is loaded by Cradle: Cradle {cradleRootDir = "H:\\Path\\to\\Project\\", cradleOptsProg = CradleAction: Cabal}
Run entered for haskell-language-server-wrapper(haskell-language-server-wrapper.exe) Version 1.0.0.0, Git revision 4cd1cf934638881e52b3eba9f70157a4b799c0e9 (dirty) x86_64 ghc-8.10.4
Current directory: H:\Path\to\Project
Operating system: mingw32
Arguments: ["--debug","."]
Cradle directory: H:\Path\to\Project
Cradle type: Cabal

Tool versions found on the $PATH
cabal: 3.4.0.0
stack: Not found
ghc: 8.10.4

Consulting the cradle to get project GHC version...
Project GHC version: 8.10.4
haskell-language-server exe candidates: ["haskell-language-server-8.10.4.exe","haskell-language-server-8.10.exe","haskell-language-server.exe"]
Launching haskell-language-server exe at:***\haskell-language-server-8.10.4.exe
haskell-language-server version: 1.0.0.0 (GHC: 8.10.4) (PATH: ***\haskell-language-server-8.10.4.exe) (GIT hash: 4cd1cf934638881e52b3eba9f70157a4b799c0e9)
ghcide setup tester in H:\Path\to\Project.
Report bugs at https://github.com/haskell/haskell-language-server/issues

Step 1/4: Finding files to test in H:\Path\to\Project
Found 8 files

Step 2/4: Looking for hie.yaml files that control setup
Found 1 cradle
()

Step 3/4: Initializing the IDE

Step 4/4: Type checking the files
2021-03-28 08:20:21.0398966 [ThreadId 3] DEBUG hls: Set files of interest to: [(NormalizedFilePath "\\\\smb.hostname.tld\\Path\\to\\Project\\src\\Main.hs",OnDisk),(NormalizedFilePath "\\\\smb.hostname.tld\\Path\\to\\Project\\Setup.hs",OnDisk)]
2021-03-28 08:20:21.6788946 [ThreadId 46] INFO hls: Consulting the cradle for "\\\\smb.hostname.tld\\Path\\to\\Project\\src\\Main.hs"
Output from setting up the cradle Cradle {cradleRootDir = "H:\\Path\\to\\Project\\", cradleOptsProg = CradleAction: Cabal}
2021-03-28 08:20:21.8741211 [ThreadId 46] DEBUG hls: Session loading result: Left [CradleError {cradleErrorDependencies = [], cradleErrorExitCode = ExitSuccess, cradleErrorStderr = ["Multi Cradle: No prefixes matched","pwd: H:\\Path\\to\\Project\\","filepath: \\\\smb.hostname.tld\\Path\\to\\Project\\src\\Main.hs","prefixes:","(\"src/Main.hs\",Cabal {component = Just \"Project:exe:Project\"})"]}]
2021-03-28 08:20:21.877141 [ThreadId 39] INFO hls: File: \\smb.hostname.tld\Path\to\Project\src\Main.hs
Hidden: no
Range: 1:1-2:1
Source: cradle
Severity: DsError
Message:
Multi Cradle: No prefixes matched
pwd: H:\Path\to\Project
filepath: \\smb.hostname.tld\Path\to\Project\src\Main.hs
prefixes:
("src/Main.hs",Cabal {component = Just "Project:exe:Project"})
2021-03-28 08:20:22.292737 [ThreadId 61] INFO hls: Consulting the cradle for "\\\\smb.hostname.tld\\Path\\to\\Project\\Setup.hs"
Output from setting up the cradle Cradle {cradleRootDir = "H:\\Path\\to\\Project\\", cradleOptsProg = CradleAction: Cabal}
2021-03-28 08:20:22.4873468 [ThreadId 61] DEBUG hls: Session loading result: Left [CradleError {cradleErrorDependencies = [], cradleErrorExitCode = ExitSuccess, cradleErrorStderr = ["Multi Cradle: No prefixes matched","pwd: H:\\Path\\to\\Project\\","filepath: \\\\smb.hostname.tld\\Path\\to\\Project\\Setup.hs","prefixes:","(\"src/Main.hs\",Cabal {component = Just \"Project:exe:Project\"})"]}]
2021-03-28 08:20:22.4903568 [ThreadId 33] INFO hls: File: \\smb.hostname.tld\Path\to\Project\Setup.hs
Hidden: no
Range: 1:1-2:1
Source: cradle
Severity: DsError
Message:
Multi Cradle: No prefixes matched
pwd: H:\Path\to\Project
filepath: \\smb.hostname.tld\Path\to\Project\Setup.hs
prefixes:
("src/Main.hs",Cabal {component = Just "Project:exe:Project"})
2021-03-28 08:20:22.7177694 [ThreadId 74] INFO hls: finish: User TypeCheck (took 1.67s)
2021-03-28 08:20:22.7197708 [ThreadId 82] INFO hls: finish: GetHie (took 0.00s)
Files that failed:
* \\smb.hostname.tld\Path\to\Project\Setup.hs
2021-03-28 08:20:22.7227757 [ThreadId 93] INFO hls: finish: GenerateCore (took 0.00s)
* \\smb.hostname.tld\Path\to\Project\src\Main.hs

Completed (0 files worked, 8 files failed)
haskell-language-server-wrapper.exe: callProcess: ***\haskell-language-server-8.10.4.exe "--debug" "." (exit 8): failed
```

LSP logs:

```
haskell-language-server: haskell-lsp:incoming message parse error. {"id":0,"result":null,"jsonrpc":"2.0"} Error in $.result: parsing () failed, expected Array, but encountered Null

haskell-language-server: haskell-lsp:incoming message parse error. {"id":1,"result":null,"jsonrpc":"2.0"} Error in $.result: parsing () failed, expected Array, but encountered Null

haskell-language-server: haskell-lsp:incoming message parse error. {"id":0,"result":null,"jsonrpc":"2.0"} Error in $.result: parsing () failed, expected Array, but encountered Null

haskell-language-server: haskell-lsp:incoming message parse error. {"id":1,"result":null,"jsonrpc":"2.0"} Error in $.result: parsing () failed, expected Array, but encountered Null
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.