tintoy / msbuild-project-tools-vscode

VS Code extension for MSBuild intellisense (including PackageReference completion).
MIT License
82 stars 16 forks source link

One unavailable package feed breaks PackageReference auto-complete #87

Open stijnherreman opened 2 years ago

stijnherreman commented 2 years ago

I'm working on a new system and I can't get the PackageReference auto-complete to work. I've seen it work just fine on other systems, but I just can't figure it out for this one and I can't find any logs either.

SDKs and runtimes:

> dotnet --list-sdks
5.0.402 [C:\Program Files\dotnet\sdk]
> dotnet --list-runtimes
Microsoft.AspNetCore.All 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

settings.json:

"msbuildProjectTools.logging.level": "Debug",
"msbuildProjectTools.logging.trace": true,

Output for MSBuild Project Tools:

Starting MSBuild language service...
MSBuild language service is running.

Screenshots: image image image

tintoy commented 2 years ago

On recent versions of VS Code, there are actually 2 different output panes (seems to be a limitation of the extension / language server APIs). You will find the logs in the other one (and in the next release the panes will have different names).

stijnherreman commented 2 years ago

OK, I got some logs now.

This is the output when pressing Ctrl+Space to find a version (second screenshot):

Finding descriptor for "textDocument/completion"
Starting: Routing Request (81) "textDocument/completion"
Converting params for Request (81) "textDocument/completion" to "OmniSharp.Extensions.LanguageServer.Protocol.Models.CompletionParams"
Requesting suggestions for NuGet package versions matching Id "Microsoft.Extensions.Options" (include pre-release: False)...
[Error - 09:03:41] Failed to provide completions.
System.Net.Http.HttpRequestException: Response status code does not indicate success: 404 (Not Found).
   at HttpResponseMessage System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at void NuGet.Protocol.HttpSource+<>c__DisplayClass13_0<T>+<<ProcessStreamAsync>b__0>d.MoveNext()
   at async Task<T> NuGet.Protocol.HttpSource.ProcessResponseAsync<T>(HttpSourceRequest request, Func<HttpResponseMessage, Task<T>> processAsync, ILogger log, CancellationToken token)
   at async Task<T> NuGet.Protocol.HttpSource.ProcessStreamAsync<T>(HttpSourceRequest request, Func<Stream, Task<T>> processAsync, ILogger log, CancellationToken token)
   at async Task<IEnumerable<string>> NuGet.Protocol.AutoCompleteResourceV2Feed.GetResults(Uri apiEndpointUri, ILogger logger, CancellationToken token)
   at async Task<IEnumerable<NuGetVersion>> NuGet.Protocol.AutoCompleteResourceV2Feed.VersionStartsWith(string packageId, string versionPrefix, bool includePrerelease, ILogger log, CancellationToken token)
   at async Task<SortedSet<NuGetVersion>> MSBuildProjectTools.LanguageServer.Utilities.NuGetHelper.SuggestPackageVersions(IEnumerable<AutoCompleteResource> autoCompleteResources, string packageId, bool includePrerelease, string versionPrefix, ILogger logger, CancellationToken cancellationToken) in C:\Development\github\tintoy\msbuild-project-tools-vscode\lib\server\src\LanguageServer.Common\Utilities\NuGetHelper.cs:line 185
   at async Task<SortedSet<NuGetVersion>> MSBuildProjectTools.LanguageServer.Documents.ProjectDocument.SuggestPackageVersions(string packageId, bool includePrerelease, CancellationToken cancellationToken) in C:\Development\github\tintoy\msbuild-project-tools-vscode\lib\server\src\LanguageServer.Engine\Documents\ProjectDocument.cs:line 524
   at async Task<List<CompletionItem>> MSBuildProjectTools.LanguageServer.CompletionProviders.PackageReferenceCompletion.HandlePackageReferenceAttributeCompletion(ProjectDocument projectDocument, XSAttribute attribute, CancellationToken cancellationToken) in C:\Development\github\tintoy\msbuild-project-tools-vscode\lib\server\src\LanguageServer.Engine\CompletionProviders\PackageReferenceCompletion.cs:line 194
   at async Task<CompletionList> MSBuildProjectTools.LanguageServer.CompletionProviders.PackageReferenceCompletion.ProvideCompletions(XmlLocation location, ProjectDocument projectDocument, string triggerCharacters, CancellationToken cancellationToken) in C:\Development\github\tintoy\msbuild-project-tools-vscode\lib\server\src\LanguageServer.Engine\CompletionProviders\PackageReferenceCompletion.cs:line 95
   at async Task<CompletionList> MSBuildProjectTools.LanguageServer.Handlers.CompletionHandler.OnCompletion(CompletionParams parameters, CancellationToken cancellationToken) in C:\Development\github\tintoy\msbuild-project-tools-vscode\lib\server\src\LanguageServer.Engine\Handlers\CompletionHandler.cs:line 202
Result was "System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.CompletionList, OmniSharp.Extensions.LanguageProtocol, Version=0.7.9.0, Culture=neutral, PublicKeyToken=null],[MSBuildProjectTools.LanguageServer.Handlers.CompletionHandler+<OmniSharp-Extensions-JsonRpc-IRequestHandler<OmniSharp-Extensions-LanguageServer-Protocol-Models-CompletionParams\,OmniSharp-Extensions-LanguageServer-Protocol-Models-CompletionList>-Handle>d__28, MSBuildProjectTools.LanguageServer.Engine, Version=0.3.15.0, Culture=neutral, PublicKeyToken=null]]"
Response value was null
Finished: Routing Request (81) "textDocument/completion" in 582ms

Through Fiddler I figured out that one of the package feeds in %appdata%\NuGet\NuGet.Config is the culprit. It's an internal feed running NuGet.Server 3.4.1 and the second request by the extension fails:

GET /NugetServer/nuget

200 OK
<?xml version="1.0" encoding="utf-8"?>
<service xml:base="http://internal-server/NugetServer/nuget" xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom">
  <workspace>
    <atom:title type="text">Default</atom:title>
    <collection href="Packages">
      <atom:title type="text">Packages</atom:title>
    </collection>
  </workspace>
</service>
GET /NugetServer/nuget/package-ids?partialId=Newtonsoft.Json&includePrerelease=False

404 Not Found

So it seems that one feed returning a 404 causes the auto-complete to stop working entirely.

tintoy commented 2 years ago

Ah - sorry about that 🙂

It was a deliberate design decision (fail fast) but maybe I can add a switch for that behaviour?

stijnherreman commented 2 years ago

A switch would be excellent. I can see how the current behaviour makes sense in case of temporary unavailability of a feed, but in this case the response will always be a 404.

tintoy commented 2 years ago

Would the ability to ignore a feed by name or URL be enough, do you think?

stijnherreman commented 2 years ago

Ignoring a feed by name sounds fine. I've looked into it some more and it comes down to NuGet.Server only supporting the v2 API.

tintoy commented 2 years ago

Oops! Sorry, it turns out I already added support for this due to a similar issue a while back (got pretty busy with work and forgot about it!)… 🤦‍♂️

https://github.com/tintoy/msbuild-project-tools-server/issues/24#issuecomment-927225346

(haven’t finished testing the new version yet but it should do what you want, as well as being a little clearer what the problem is if a feed doesn’t support the required NuGet APIs)

I’ll try to get a final version published sometime this week but feel free to install from the linked VSIX package in that other issue in the meanwhile if you need to 🙂