-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Pass correct parameterName to ArgumentException #33763
Comments
Estimates:
|
A fixer is tough here because we don't know what message to insert into the parameter list. Perhaps we could pass in [Edit by @bartonjs: Digging in a little deeper, it looks like |
Based on this guidance, we can update the estimates:
|
Just found we have analyzer for ArgumentException and its descendants, some rules might not covered and no fixer implemented I assume i would update this analyzer (if needed) and add fixer implementation. @mavasani please let me know what you think |
There is case not covered above: public async Task ArgumentException_NoArguments_Warns()
{
await VerifyCS.VerifyAnalyzerAsync(@"
public class Class
{
public void Test(string first)
{
throw new System.ArgumentException();
}
}",
GetCSharpNoArgumentsExpectedResult(6, 31, "ArgumentException"));
} The question is do we want fixer for this (possibly |
Same question for other similar cases with empty string or white space, should we provide fixer? [Fact]
public async Task ArgumentException_EmptyParameterNameArgument_Warns()
{
await VerifyCS.VerifyAnalyzerAsync(@"
public class Class
{
public void Test(string first)
{
throw new System.ArgumentNullException("""");
}
}",
GetCSharpIncorrectParameterNameExpectedResult(6, 31, "Test", "", "paramName", "ArgumentNullException"));
}
[Fact]
public async Task ArgumentNullException_SpaceParameterArgument_Warns()
{
await VerifyCS.VerifyAnalyzerAsync(@"
public class Class
{
public void Test(string first)
{
throw new System.ArgumentNullException("" "");
}
}",
GetBasicIncorrectParameterNameExpectedResult(4, 31, "Test", " ", "paramName", "ArgumentNullException"));
} |
I searched for |
I don't know that there's enough cleverness to guess as to what argument someone meant if they didn't give a name (vs gave a name, but passed it as the wrong parameter). |
Are we holding the bar to "essentially no noise" ? As this is a pattern we use in a fair number of places. Eg., (1) because the parameter name was historically different, although we should probably just 'break' those (2) because it's in a throw helper eg private static Exception HashAlgorithmNameNullOrEmpty() =>
new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, "hashAlgorithm"); Would I be expected to suppress the warning on this line? |
My personal refinement/rise-and-repeat would say "hmm, if there are no parameters to a method and it's throwing an ArgumentException, there's not really anything to report on; it must be a helper". If the helper took the message as a parameter, then it'd require suppression... assuming that's not a commonish pattern. But the general flow on anything reactive like this is definitely "write it, see too many violations, figure out how to get it down to a manageable number"; like with stackalloc in a loop. |
@danmosemsft in addition to @bartonjs's comment our "Definition of Done" steps for analyzers might give you more info
|
@buyaa-n That sounds good. This rule should likely tune or supersede CA2208. Going through the discussions in this issue, I wanted to point out that the rules written in roslyn-analyzers repo have the ability to define end-user configurable .editorconfig options. We have had large number of scenarios where options are very helpful when there is no single, perfect analyzer implementation:
|
@buyaa-n / @danmosemsft - I've revised our definition of done a bit. Here's the updated list. We'll get this documented somewhere centrally very soon.
|
I have added some more tests to see what analyzer scenarios are not covered and found one scenario not covered. Which is |
Yep, if there's already an analyzer for it then there's no need to repeat it. |
We have that rule enabled in dotnet/runtime: runtime/eng/CodeAnalysis.ruleset Line 57 in d1006ce
I might be remembering incorrectly, but I thought @danmosemsft told me he found some occurrences of this in our codebase; if that's true, it'd be good to understand what the rule is missing, and potentially augment it. |
I feel like I've seen some, too. But maybe it was just in test projects? |
I was planning to test this and ArgmentException analyzer against runtime by increasing severity level, I thought they are not warning because of the severity level low, but didn't know it was enabled like this, anyways I will look into that and test them with runtime to get some numbers which would help us with potential augmetning |
The UseNameofInPlaceOfString analyzer is enabled in the runtime repo and running just fine, as @bartonjs said i assume those occurrences were on test projects . Also I had enabled InstantiateArgumentExceptionsCorrectlyAnalyzer to test against runtime repo and got lots of valid/invalid warnings, sent the report by email. Please let me know your thoughts about it |
I have no memory of anything I may have said 😺 Using simple regexes right now, I only see some minor hits like |
Question: what we want/need to do with the test failures on runtime CC @bartonjs @jeffhandley @stephentoub @terrajobst |
In the "Fix warnings found by the analyzer" PR got more suggestions for improving the analyzer:
I am planning to add these improvements, please let me know if you have any concerns with the above @terrajobst. @mavasani is there any config option for setting the target method accessibility level? Any suggestions about that? |
Yes, we have tons of analyzers that only want to run on public API surface by default, but want to give end users the option to configure the analyzed API surface. We have an extension method and an existing editorconfig option that should exactly meet your requirements. API: You can invoke |
Great, thank you @mavasani! |
Reopening the issue as we need to fine tune the rules more and also for tracking the fix warnings in runtime repo and update the doc accordingly. Gonna add following to the rule:
|
This explicitly violates Framework Design Guidelines, we should not do it.
You'll want PM signoff on that... since I recall it being something @terrajobst explicitly was against on the call. |
Oops sorry, I thought it would be more convenient 😛, canceling this
Sure thing, @terrajobst havign issue with the following case, doesn't make sense to throw with the argument again, doesn't have a message to embed the property info, for now only can suppress public ChainedConfigurationProvider(ChainedConfigurationSource source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (source.Configuration == null)
{
#pragma warning disable CA2208 // Instantiate argument exceptions correctly
throw new ArgumentNullException(nameof(source) + "." + nameof(source.Configuration));
#pragma warning restore CA2208
}
} |
Immo's suggestion for the later case: ANE is not right thing to throw here as arguments was not null, better to use argument exception with appropriate message and keep nameof(source) as paramName. I will apply this suggestion in my PR, would double check the doc as these are public APIs, i think i shouldn't change the exception if it is documented so. So the analyzer will not be updated, but gonna keep this open until runtime fixes merged |
Another suggestion came up from the "Fix warnings found in runtime PR" was apply the analyzer only for desired ArgumentException descendants to exclude user-defined types or apply to all ArgumentException-derived types (including itself) that have a constructor accepting a paramName parameter, including user-defined types. |
Seems like a good candidate for an analyzer option to allow users to select either configuration. |
@mavasani I was thinking to apply whichever implementation would more efficient/faster, but let the user choose which one to apply might be even better |
After looking constrcutors of ArgumentException derived types in .Net |
Need to turn on the analyzer on runtime repo after its updates shipped to nugget, but i think we don't need to keep it open for that |
Find places where
nameof(...)
is passed as the first (rather than second) argument toArgumentException
. Also places wherenameof
is used as the argument name in anArgumentException
(or derived type) but where it's not referring to a parameter.Category:
ReliabilityUsageExamples to detect:
Single-argument nameof (or a literal string that matches the name of a parameter). Fixer: change to call the two argument constructor, pass null for the first parameter.
Two argument call, first one looks like the parameter. Flip the argument order.
Two argument call, paramName is a literal, but not a parameter name. (No fixer, just squiggle the argument.)
Two argument call, paramName is a literal, but not nameof. (Fixer: use nameof)
Examples to not detect:
Probably wrong (based on the parameter names), but probably shouldn't warn; since we're kinda guessing.
When the parameter name comes from a variable rather than a literal, don't squiggle.
The text was updated successfully, but these errors were encountered: