Throw a graceful exception if the SDK needed by a project is not installed #337
Description
Right now if you use MSBuildLocator to locate an MSBuild for an SDK-style project, and the SDK is not installed, you get a particularly unfriendly error mode. An exception is thrown that says "An exception of type System.InvalidOperationException was thrown: Failed to find all versions of .NET Core MSBuild. Call to hostfxr_resolve_sdk2. There may be more details in stderr.". In some cases (like the C# extension) stderr was written out to a child process, so unless you go digging in a bunch of trace logs, you won't see the real cause of the problem.
Chatting with the SDK team, hostfxr_resolve_sdk2 has been given some new APIs to help us deal with this case:
- Add requested version to hostfxr_resolve_sdk2 dotnet/runtime#68355
- Add a flag to hostfxr_resolve_sdk2_flags_t to silence error messages dotnet/runtime#119729
With this we can know the requested version and global.json, so we could instead throw a smart exception that says the SDK specified in the global.json could not be found. If we threw a more concrete exception type (like an SdkNotFoundException) we could also give a nice message to the user in that case. I'd say a generic InvalidOperationException might still be appropriate if the underlying failure isn't understood.
It's possible #331 is a duplicate of this issue as well; that's the same symptoms but the described scenario is a bit different, but maybe improvements here help that too.
Activity
jasonmalinowski commentedon Oct 2, 2025
I think I'm going to reactivate this because for the C# extension case I originally filed this for Theodore Tsirpanis (@teo-tsirpanis)'s change isn't quite enough -- we ideally want a richer exception (and not just an InvalidOperationException) for us to identify the missing SDK case that we can then pop up a short message to the user for that.
#341 though is still a great improvement, so we'll make sure we pick it up.
teo-tsirpanis commentedon Oct 2, 2025
Would this be OK? I held off from changing the exception type in #341, because of the potential breaking change.
jasonmalinowski commentedon Oct 2, 2025
I think for the missing SDK case, we really want a rich exception that has the expected version and the path to the global.json which the resolve stuff can give us directly. Although I guess I should check my assumption -- in the case of the missing SDK, how long is that error detail? Is it a single line or many lines long?