-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exception message for AmbiguousMatchException should include the name #18255
Comments
That makes sense to me. @weshaggard @jkotas, any thoughts on this? |
This is true for majority of the exception messages. It is pretty rare for exception messages to include the bad argument value ... you have to pretty much always fire up the debugger if you need it (or get it in some other way). If there is something particular about this one to make it really worth it to include the bad argument value, I do not see a problem with it. But we need to think about where reasonable balance is - I do not think we want to be adding the bad argument values to exception messages everywhere. |
Not to be simplistic, but: why not? Allow me to draw the equivalent to a unit testing framework (since that's something I know a little bit about): Your argument would be the equivalent of saying "You don't need to add expected and actual values into your unit test messages, because they could find that out in a debugger". While that's true, it also diminishes the value, and at what cost? |
The difference is in cost/benefit. Adding actual/expected values in unit test messages can be done in central place. It is worth it to add a few more lines in central place for this. Adding bad argument values to exception messages everywhere would change like 10000's places just for corefx, bloat the code quite a bit. I do not think it is worth it. |
A similar change to Personally, I think clearer exceptions messages are worth some code bloat. |
|
Next steps: Find the places which throw it - try to implement it consistently. |
Let's tentatively try to make this a little better in 5.0 for debuggability. Though it's low-priority compared to other reflection work so it may still slip below the cut line. Edit: We shouldn't strive for 100% coverage. Just target scenarios where we don't have to contort the code to make the exception message a little better. |
Like #34703 |
My 2c. Many times issues first show up in logs. A debugger may not be available - nor dump file - nor even a repro. If by changing some localized places to add some value that we have easily available into that message, we can make some of these diagnosable without further work. It seems a place where relatively small work in a library is highly leveraged. This is why we added keys to key not found exceptions, paths to file not found exceptions. Of course there are cases where it is not worth it but there are still plenty of cases we we do not have a good reason to not do it.
I don't think consistency for its own sake is important in these messages. In making changes of this sort in the past, I just skipped cases where it is difficult/impossible to supply the value. Eg., some of the IO exception paths. Most of our exception types were originally designed to have an optional "parameter" -- they already come in helpful and less helpful forms. We just prefer the more helpful form if we can. |
Not required to ship 5.0 product. Setting milestone. |
Still seems like a valid request; there are ~24 cases currently: https://github.com/dotnet/runtime/search?q=%22new+AmbiguousMatchException%22&type=code |
If I were to take this on, would it be reasonable to add a format string to <data name="Arg_AmbiguousMatchException_Detailed" xml:space="preserve">
<value>Ambiguous match found for: '{0}'.</value>
</data>
<data name="AmbiguousImplementationException_Detailed" xml:space="preserve">
<value>Ambiguous implementation found: '{0} {1}'.</value>
</data> Then in the throw-sites, would grab the argument string of whatever we're ambiguous about and format away. For the throw-sites where where we HAVE a We could just use var foo = "Hello World";
var footype = foo.GetType();
Console.WriteLine(footype.ToString());
var data = footype.GetProperty("Length");
Console.WriteLine(data.ToString());
Would that case warrant two new format strings or is there a standard helper I would use to gen up a runtime-safe human-readable name of the declaring type + member (e.g. "String.Length")? |
Maybe |
Additionally, it's plausible in cases like DefaultBinder.cs we actually have a lot more than just one method... is there value in having this exposed in more detail? |
re parallel strings, we do this for IO, eg.,
and of course try our best to only use the one with the more info, but they are both there. Edit: BTW, we try to put single quotes around replacement markers unless they're numbers. Not start with a replacement marker. and end with a period. |
I don't own this area but I think you'd be welcome to take it @IDisposable. do you want me to assign to you? |
Cool, thoughts on formatting and if emitting details where we have multiple ambiguous possibilities? I'm thinking that (for example in DefaultBinder), we could just emit the |
Updated example format strings per replacement standard mentioned above |
I think an area owner like @steveharter should advise. |
Draft PR #84512 for commentary as to my approach and to let the build bots test it :) This take leverages the places where we have I did NOT address dumping all the ambiguous matches because that would incur not only a huge change to the |
I think the issue is asking for adding a member info in case no member info is provided. i.e: I don't feel we really need to change internal static AmbiguousMatchException GetAmbiguousMatchException(MemberInfo memberInfo)
{
Type? declaringType = memberInfo.DeclaringType;
return (declaringType is not null)
? new AmbiguousMatchException(SR.Format(SR.Arg_AmbiguousMatchException_Detailed, declaringType, memberInfo))
: new AmbiguousMatchException(SR.Format(SR.Arg_AmbiguousMatchException_Simple, memberInfo));
} |
Fundamentally, this is an indication of a bad argument, without telling you what the bad value is, which usually demands that you fire up the debugger to figure it out. It would be helpful to know what the ambiguous name actually was.
The text was updated successfully, but these errors were encountered: