CsWinRT
CsWinRT copied to clipboard
Unhelpful HRESULT error messages in .NET
Describe the bug Often in .NET we get pretty unhelpful HResult errors. Example:

Apparently this means ERROR_MRM_RESOURCE_TYPE_MISMATCH.
It would be nice with better more helpful/meaningful error messages thrown, instead of just an HRESULT.
Steps to reproduce the bug
- Create a new WinUI app
- Add the following code:
Microsoft.ApplicationModel.Resources.ResourceManager rm
= new Microsoft.ApplicationModel.Resources.ResourceManager();
for (uint i = 0; i < rm.MainResourceMap.ResourceCount; i++)
{
var value = rm.MainResourceMap.GetValueByIndex(i);
}
var ctx = rm.CreateResourceContext();
ctx.QualifierValues.Add("scale", "100");
var val = rm.MainResourceMap.GetValue(@"Files/Images/LockScreenLogo.png", ctx);
var path = val.ValueAsString;
var data = val.ValueAsBytes; // throws HRESULT 0x76D3A8B2
Expected behavior An error message that actually tells me what I did wrong, so I can move on and get my work done.
Version Info
NuGet package version: 0.5.5
| Windows 10 version | Saw the problem? |
|---|---|
| Insider Build (xxxxx) | |
| May 2020 Update (19041) | |
| November 2019 Update (18363) | |
| May 2019 Update (18362) | |
| October 2018 Update (17763) |
Additional context
https://task.ms/37784956
What version of Visual Studio are you using?
Using Visual Studio 2019 Preview, Just My Code enabled, default exception handling, and the new (default) Exception Helper, I get:

If you could attach a repro project, that'd be helpful too. I can't reproduce your exact error.
@riverar I didn't see any difference in 16.10p1. Upgraded to preview 2, and that version won't even load (or create) the packaging project (likely because I got net6 installed).

@dotMorten Yep, all broken here too in all Visual Studio instances. Not sure what's up, which is ironic given the title of this issue.
Even so, while the error you got is better, I still dont think its super helpful. Also interesting that the error in your screenshot has a different hresult value - I wonder if we're even hitting the same exception.
@dotMorten were you able to get past the packaging project failing to load? If not, try adding a global.json file to your solution folder and specify a .net5 sdk version number. This seems to work for me (and also fixes not being able to create a new solution).
The ILLinkTasksAssembly error is a VS bug for VS 16.10 preview2 with .net 6.
for the C++ exception, if you hit f5, you will see the nicer System.Runtime.InteropServices.COMException Rafael showed. Or if you uncheck the checkbox when C++ exception shows up (or change in the exception settings for C++ Exceptions -> winrt::hresult_error), you will get to that COMException directly.
Mapping HRESULT to the windows error message is the default projection behavior. Changing to a custom message is both unnecessary and not easy (i tried to add a custom message while throwing, but it doesn't show up in the COMException). I think this is probably by design.
Thanks @huichen123.
for the C++ exception, if you hit f5, you will see the nicer System.Runtime.InteropServices.COMException
This does seem a bit counter-intuitive that you have to continue on an error to get a better error. Can we improve that?
Changing to a custom message is both unnecessary and not easy
I'm not asking for a custom message, but a better message that's helpful and guides the developer towards how to fix their code. "Invalid ResourceCandidate Type" says nothing about that I can't get the data as bytes as I attempted. It sounds like the entire resource lookup failed. If the error had instead hinted that the data can't be read as bytes, it would be clear that I need to try the other property. I'd like to think of exception messages as not error messages, but as help messages. Poor error messages are one of those "death by a 1000 razor cuts" things that prevents people from quickly becoming successful.
I don't know what's the default exception setting for winrt::hresult_error. But if you don't want to see that exception, the UI is made very easy to turn it off.
Regarding custom message, actually it does get to the other side. However, it's not the primary message, and I am not sure how useful that will be.

However, it's not the primary message, and I am not sure how useful that will be.
Generally the goal of this issue was to point out a poor message that could be better. My main grief working with C#/WinRT is generally the error messages, and had promised to log them when I see them. It's easy to dismiss issues around error messages because they will still be error messages, and it's ultimately the user who did something wrong, and it's a non-issue once they fix their issue. But that ends up creating a horrible developer experience. But also consider often errors aren't caught until production and a good error message alone can quickly lead to a fix, without having to work with the customer on getting dumps generated.
Line of code where it's being thrown for reference: https://github.com/microsoft/ProjectReunion/blob/1714557cad5e740c0153e451fbf0311c8e5bdfc1/dev/MRTCore/mrt/Microsoft.ApplicationModel.Resources/src/ResourceCandidate.cpp#L55
This error isn't thrown deep down where some resource candidate is being looked up. It's thrown right on the property accessor where a better message could have been used.
The easiest "improvement" is to disable native debugging. That will land you directly on the COMException. Otherwise breaking on hresult_error shouldn't be off by default because it's very helpful to people who write C++.
Perhaps a better solution is to have VS ignore internal exceptions coming from WinUI, instead letting the language reflection do the job.
Or making the VS debugger show a better error message for winrt::hresult_error (this one I like because C++ devs benefit too)
The easiest "improvement" is to disable native debugging. That
Thanks. This is rather ironic actually, as generally I get better error information that can actually inspect with this turned on, rather than a generic COM exception.
Going through "aged" issues, and this one seems like a good one to come back around to. The discrepancies between native & managed debugging seems like something that we should be able to work with the VS folks on improving. Adding Mike Battista as a co-owner on this issue as welll.