csharpanalyzers / exceptionalresharper Goto Github PK
View Code? Open in Web Editor NEWExtension for ReSharper which analyzes thrown and documented C# exceptions and suggests improvements
License: Microsoft Public License
Extension for ReSharper which analyzes thrown and documented C# exceptions and suggests improvements
License: Microsoft Public License
When using nullable types a suggestion appears after calling property Value. This should not happen if it was checked before that the property has a value. Example:
var text = source.IsCity == null ? "unknown" : (source.IsCity.Value ? "yes" : "no");
Exceptional gives a warning about an exception not being in method documentation when the following criteria are met:
Recommended behavior in this case is to provide no error as the exception has been documented. Users can simply click on the (i) icon in the well to go to the interface or use the keyboard shortcuts provided by Resharper to navigate to the interface and see the documentation.
The comment is not always correctly analyzed: Sometimes it works sometimes it does not work...
The hints should only be displayed when the "XML documentation file" option is checked in the project properties.
There is no need to always document the exceptions thrown by a method (especially in a small test project).
There should be a context action to catch all exceptions in one take.
Hi, if you wrote a test method like this,
public` static void TestMethod() {
if (true) throw new ArgumentException("<>&\"\'");
throw new NotImplementedException();
}
and apply "Add documentation for exception [Exceptional]" context action,
you'll get XML comment like this.
/// <exception cref="ArgumentException"><>&"'</exception
But <
, >
, &
, "
and '
should be escaped in XML comment.
Please consider to add conversion into entity reference.
Thanks in advance.
I'd appreciate any help getting around the following error when attempting to update Exceptional (using the extensions gallery in R# 2016.2):
Error registering mapping for catalog assembly “ReSharper.Exceptional.2016.2, Version=0.7.8.0, Culture=neutral, PublicKeyToken=null”. An item with the same key has already been added. An item with the same key has already been added. Execute Build Step Runnable JetBrains.Platform.VisualStudio.Core!JetBrains.VsIntegration.UI.WindowManagement.Install.VsPackageEmitsToolWindowIcons::CollectToolWindowIcons#3 has failed. The build step method JetBrains.VsIntegration.UI.WindowManagement.Install.VsPackageEmitsToolWindowIcons::CollectToolWindowIcons has thrown an exception. Exception has been thrown by the target of an invocation. An item with the same key has already been added. Cannot index assemblies in the application packages. There are at least two assemblies with the same simple name “ReSharper.Exceptional.2016.2, Version=0.7.8.0, Culture=neutral, PublicKeyToken=null” in packages Exceptional.2016.2 and Binbin.Exceptional.2016.2. An item with the same key has already been added.
Consider the following piece of code:
public class MyClass
{
public int MethodA()
{
MethodB(); // Issue not detected.
throw new ArgumentException(); // Issue detected.
}
public int MethodB()
{
MethodC(); // Issue not detected.
throw new InvalidOperationException(); // Issue detected.
}
public void MethodC()
{
throw new NotImplementedException(); // Issue detected.
}
}
It would be nice if Exceptional would show issues for the calls to MethodB / MethodC too BEFORE I fix them and not just ignore them.
If you throw some sort of exception, and document the method as throwing a base type of that exception's type, you'll get two inappropriate errors from Exceptional. For example, in the following,
(1) Task.Delay() can throw a TaskCanceledException;
(2) A TaskCanceledException is an OperationCanceledException;
(3) The method is documented as throwing OperationCanceledException
... and yet Exceptional gives the following seemingly inappropriate messages:
(1) Exception 'OperationCanceledException' is not thrown
(2) Exception 'TaskCanceledException' is not documented
/// <summary>
/// The blah async.
/// </summary>
/// <param name="cancellationToken">
/// The cancellation token.
/// </param>
/// <returns>
/// The <see cref="Task"/>.
/// </returns>
/// <exception cref="OperationCanceledException">
/// The operation was canceled.
/// </exception>
public async Task BlahAsync(CancellationToken cancellationToken)
{
await Task.Delay(37, cancellationToken).ConfigureAwait(false);
}
Are you planning on implementing support for R# 2017.1?
Please do, this is a fantastic plugin which I really need! 😅
I multple parameters throws ArgumentNullException, it is only possible to autogenerate documentation for one of the. The highlighting of the missing documentation disappears, after adding it for the first ArgumentNullException. The Following code...
public Guid Import(Stream fileData, string fileName)
{
if (fileData == null) throw new ArgumentNullException("fileData");
if (fileName == null) throw new ArgumentNullException("fileName");
}
Generates the following documentation:
/// <exception cref="ArgumentNullException"><paramref name="fileData"/> is <see langword="null" />.</exception>
public Guid Import(Stream fileData, string fileName, Guid? cachedFileId)
{
if (fileData == null) throw new ArgumentNullException("fileData");
if (fileName == null) throw new ArgumentNullException("fileName");
}
Whenever I do something like this:
catch (Exception e) when (e is SomeException || e is SomeOtherException)
Exceptional gives me the message: "Usage of catch-all clauses is not recommended."
Unless I'm seriously misunderstanding the purpose of this suggestion, I don't think it's appropriate here. It's not a catch-all clause - it's only catching certain Exception types.
If you catch Exception just to try to do some logging or something, and then rethrow it, you get several messages from Exceptional, none of which seem terribly appropriate in this particular type of usage.
Additionally, and I think more importantly, you can't suppress them. But I'll open that up as another ticket.
Example:
public void Blah()
{
try
{
Console.WriteLine("Doing something");
}
catch (Exception e)
{
Console.WriteLine("Oh no! " + e.Message);
throw;
}
That gets:
(1) Usage of catch-all clauses is not recommended
(2) Exception 'Exception' is not documented
(3) Throwing 'System.Exception' is not recommended
Exceptional warnings are showing even if i use any number of comments to disable them.
Nothing works:
// ReSharper disable All
// ReSharper disable once ExceptionNotDocumented
// ReSharper disable ExceptionNotDocumented
[SuppressMessage("ReSharper", "ExceptionNotDocumented")]
The only things I can do to get the warnings to disappear are catch the exception or document it, there is no way to suppress it.
When there are multiple exceptions that can be caught, Exceptional fails after creating the try..catch block for the first exception. This is true whether Exceptional has created the try..catch block itself or is just in an existing try..catch block.
Error reported: Cannot perform this action, most likely because of errors in the source code
See attachment
void DoStuff(string value) {
throw new ArgumentNullException(nameof(value));
}
1.Alt-enter on "throw" line
2.Select "Document exception"
3.Generated XML doc has empty parameter name
Using a UriBuilder and Exceptional in a Portable Class Library causes Exceptional to suggest documenting UriFormatException. But this exception doesn't exist in a PCL.
Easily replicated in a new class.
public class Class1
{
/// <exception cref="UriFormatException"></exception>
public string ExceptionalTest()
{
var uriBuilder = new UriBuilder("http://google.com");
return uriBuilder.Query;
}
}
Exceptional says that this code can give ArgumentNullException:
if (foo != null)
a = foo.FirstOrDefault();
Without using the null coalescing operator in C#6, Exception shows me "Add documentation for ArgumentNullException" for the following code, which is good:
var results = GetAListSomewhere();
var result = results.FirstOrDefault(); //<--- PROMPT HERE
return result;
However, the prompt is unnecessary here, as the method would not be called.
var results = GetAListSomewhere();
var result = results?.FirstOrDefault(); //<--- PROMPT HERE
return result;
Try to detect redundant catch clauses by examining exceptions thrown from inside of try block.
It'd be very useful if Exceptional could also recognize these, in cases like (the code I'm looking at now):
public static Action WithFailFast ([NotNull] this Action action)
{
Contract.Requires<ArgumentNullException> (action != null, "action");
As it is, Exceptional either ignores such exceptions if they are not documented, or if they are documented, reports them as unnecessary exception documentation.
Thanks!
Consider:
catch (Exception e)
{
throw new OuterException(e, "Foo");
}
Here Exceptional suggests CA "Include caught exception as inner exception" which incorrectly appends x to the end of the argument list:
throw new OuterException(e, "Foo", e); // won't compile
Perhaps OuterException doesn't follow the standard convention, but in my particular case it cannot be avoided.
I have a method like:
/// <summary>
/// Validates against Range attribute if defined. If method returns without exceptions it is validated
/// </summary>
/// <exception cref="System.ComponentModel.DataAnnotations.ValidationException">The validation failed</exception>
private void Validate(string propertyName, object value) {
PropertyInfo propertyInfo = GetType().GetProperty(propertyName);
var attributes = propertyInfo.GetCustomAttributes<System.ComponentModel.DataAnnotations.ValidationAttribute>();
System.ComponentModel.DataAnnotations.Validator.ValidateValue(value, new System.ComponentModel.DataAnnotations.ValidationContext(propertyInfo.Name) { DisplayName = propertyInfo.Name }, attributes);
}
When i call it from another method Exceptional handles it as axpected. But when I apply to the setter of a property like this:
/// <exception cref="ValidationException" accessor="set">The validation failed</exception> public int MyProperty { get {return _myBackingField; } set { Validate(nameof(MyProperty,value); _myBackingField = value; } }
Then it gives me 2 warnings:
So it seems that it does not recognize it as the same exception but I have tried with complete namespace declarations and still it does not recognize it. So it should not be ambigous.
Maybe the problem is that the intellisense on System.ComponentModel,DataAnnotations.Validator.ValidateValue does not have the exception documented. But it does throw it, and it is documented on MSDN.
If this is the problem it would be better if it respected my comment so the only warning I get is for my Validate method. Not the 200 places where I use it
There should be a context action to document all exceptions in one take.
For this code here, I see a prompt telling me that it is possible to throw an InvalidOperationException
(even though it won't) - which is good behavior.
int? bar = null;
var foo = bar.Value; //<-- PROMPT HERE
However, when I check .HasValue
, which is pretty much a solid guarantee that calling .Value
will not throw an InvalidOperationException
, I still get the same prompt.
int? bar = null;
int foo;
if (bar.HasValue)
foo = bar.Value; //<-- PROMPT HERE
else
foo = 0;
While documenting thrown exceptions the documentation should be also applied to the base type.
Should it be synchronized or maybe it should be placed only on the base class?
What about 'not thrown' analysis? Should we analyse all derivates?
There is an error when there is a catch clause hidden by the preceding more general one. Right now R# has a fix to remove that clause. There should be another possibility to move that specific clause before that general one.
Manage dependencies between interfaces and its implementations so that the implementations throw exceptions declared on interface.
Sizes:
◾128x128: For the R# download page and the plugin package
◾16x16: For the R# options dialog (generic one already available)
throw new ArgumentNullException(nameof(transaction));
generate:
/// <exception cref="ArgumentNullException"><paramref name=""/> is <see langword="null" />.</exception>
better:
/// <exception cref="ArgumentNullException"><paramref name="transaction"/> is <see langword="null" />.</exception>```
Hello,
Exceptional is a great plug-in, really well done! 👍
But today I recognized that exceptions which are documented within a component are not shown in the interface to this component, which calls the method, which has a documented exception.
Is there any possibility to solve this problem?
Thank you for following answers.
Hi, I found that this extension doesn't work properly with properties.
For this code, Exceptional suggests "Exception 'IOException' is not documented." (+2 more suggestions):
public string Prop1 {
get {
Directory.CreateDirectory("");
return "";
}
}
After adding documentation for IOException according to this suggestion:
/// <exception cref="IOException" accessor="get">The directory specified by <paramref name="path" /> is a file.-or-The network name is not known.</exception>
public string Prop1 {
get {
Directory.CreateDirectory("");
return "";
}
}
But the suggestion does not disappear. Seems to have failed to scanning.
I'm having issues setting an exception for ArgumentOutOfRangeException from the property
System.Environment.StackTrace.
My exception definition is as follows:
System.Environment.StackTrace,System.ArgumentOutOfRangeException
Am I making a basic error or is something wrong?
This code sample, while obviously throwing a NullReferenceException, does not trigger any form of warning or quick fix from Exceptional.
var s = (IEnumerable)null;
foreach (var e in s) {}
Exceptional should be aware of possible exceptions triggered by the use of keywords like foreach and await.
Implement analyzer and quickfix to aggregate multiple ArgumentNullExceptions into one:
This should be transformed from...
/// <exception cref="ArgumentNullException"><paramref name="a"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException"><paramref name="b"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException"><paramref name="c"/> is <see langword="null" />.</exception>
public void Do(object a, object b, object c)
{
... to:
/// <exception cref="ArgumentNullException"><paramref name="a"/> or <paramref name="b"/> or <paramref name="c"/> is <see langword="null" />.</exception>
public void Do(object a, object b, object c)
{
This issue is coming from: https://exceptional.codeplex.com/workitem/11005
Finally I figured out how to get my local changes to be installable in Resharper 2016.2, but it took a while unfortunately.
For now and for me locally I just copied the nuspec file for 2016.1 and changed the required wave to include up to 7.0 (=> 2016.2) which seems to work, but I don't know if that's sufficient.
In which way does Exceptional require a minimum ReSharper version for single functions yet? is it really necessary to use separate projects, or could it be simplified and just built for different targets?
In any case I would appreciate an up to date how-to about how to contribute (including how to build and test locally as that was a major part of what I tried to do).
Update: it's not sufficient as far as I can see:
Looks like the jetbrains references have to be upgraded as well.
Given that: Is there a reason why ReSharper 2016.2 is published in the resharper plugin repository, but not yet included in this project?
Sometimes exceptions are never thrown or should net be caught by the caller.
As example
Thread.Sleep(100)
Or
if(something != null)
{
WillThrowArgumentNullException(something)
}
If have already implemented a solution for such cases.
/// <exception cref="ArgumentException">Thrown when foo is 5</exception>
/// <exception cref="ArgumentOutOfRangeException">Can be ignored because argument of sleep is always valid</exception>
public void HasIgnoredExceptions(int foo)
{
Thread.Sleep(100);
if (foo == 5)
{
throw new ArgumentException("foo");
}
}
If a exception comment starts with "Can be ignored" this exception can be ignored by the caller.
Any Ideas for improvements?
Any idea when Exceptional will be out for the latest Resharper release 2016.3? I miss it already!
The exception in class Modul has squiggles. Here was not supported the inheritdoc tag.
example:
public interface IModul
{
/// <summary />
/// <exception cref="ArgumentNullException"><paramref name="mainMenu"/> is <see langword="null" />.</exception>
void SetMainMenu(MenuStrip mainMenu);
}
public class Modul : IModul
{
/// <inheritdoc />
public void SetMainMenu(MenuStrip mainMenu)
{
if (mainMenu == null)
{
throw new ArgumentNullException("mainMenu");
}
}
}
I'd like to tell Exceptional to disable processing on any classes that have the [NUnit.Framework.TestFixture]
attribute.
You can't suppress messages. None of these three in this example actually suppress the associated errors; all of these were generated by the built-in quick fix that is intended to suppress them, not manually.
public void Blah()
{
try
{
Console.WriteLine("Doing something");
}
// ReSharper disable once CatchAllClause
catch (Exception e)
{
Console.WriteLine("Oh no! " + e.Message);
// ReSharper disable once ExceptionNotDocumented
// ReSharper disable once ThrowingSystemException
throw;
}
Pretty sure suppressions don't work in various other situations, too, but this was a convenient example.
Given the following method:
public static void DoAction(Action action)
{
action();
}
Exceptional is telling me that an exception System.Exception should be documented because action may throw anything. However, suppose I know that Action will only throw System.IOException - can there be some way to tell Exceptional that that is the case, and that only the IOException needs to be documented in DoAction?
It seems to me that a good way to do this could be with attributes:
public static void DoAction([Throws(typeof(System.IOException))] Action action)
{
action();
}
Similarly, if I know it won't throw anything, it could be either one of:
public static void DoAction([Throws] Action action) // Empty attribute parameter list
public static void DoAction([NoThrow] Action action)
Although I realise that this would require a NuGet package or something in addition to the resharper plugin.
Consider the following bit of code:
try
{
if (soundFile.PlaySync)
{
// ReSharper disable once ExceptionNotDocumented
player.PlaySync(); // Block thread while playing sound
}
else
{
// ReSharper disable once ExceptionNotDocumented
player.Play(); // Play asynchronously
}
}
// ReSharper disable once CatchAllClause
catch (Exception ex) when (ex is FileNotFoundException ||
ex is InvalidOperationException ||
ex is TimeoutException)
{
log.LogFormat(Level.Error, "Error occurred while trying to play sound. Exception: {0}", ex);
}
Exceptional now gives warnings about not catching the specific exceptions that could be thrown by PlaySync and Play. However, I am catching those specific exceptions using the exception filter.
It would be nice if Exceptional detected this and would not give me those warnings.
The comment
// ReSharper disable once VirtualMemberCallInContructor
is spelled incorrectly. It should instead read
// ReSharper disable once VirtualMemberCallInConstructor
Example:
FileNotFoundException exists in two namespaces:
System.IO.FileNotFoundException
MyProject.Shared.FileNotFoundException
The following code:
public void Test()
{
throw new Shared.FileNotFoundException("");
}
generates this documentation:
/// <exception cref="FileNotFoundException">Condition.</exception>
public void Test()
{
throw new Shared.FileNotFoundException("");
}
The validation of the documentation complains about the ambiguous reference.
If you then specify the namespace when throwing the exception, the validation can't detect that the exception is documented, and the validation of the documentation, tells that the exception is never thrown:
/// <exception cref="Shared.FileNotFoundException">Condition.</exception>
public void Test()
{
throw new Shared.FileNotFoundException("");
}
When I click on the "More info..." link in the ReSharper extensions window, a new browser window opens and shows the old Codeplex site. The link should now point to the GitHub site, because the Codeplex site seems to be inactive.
foreach (object key in Data.Keys)
{
object value = Data[key]; // Data is an IDictionary
// ...
}
The code above warns of NotSupportedException
, which occurs when setting a value, not getting it. (Specifically, in this case, the exception is thrown when setting a value on a read-only dict, or when the object has a fixed size and the key doesn't exist.)
When I use exceptional to generate the xml comments for a potential ArgumentOutOfRangeException in both the getter and setter, it generated the following:
/// <exception cref="ArgumentOutOfRangeException" accessor="get">Index is out of range.</exception>
/// <exception cref="ArgumentOutOfRangeException" accessor="set">Index is out of range.</exception>
The problem is that Exceptional fails to see the exceptions as documented because of the accessor attribute in both, that it generated. It keeps warning that the exception is neither documented or caught. On top of this, it also begins warning that the exceptions it generated documentation for are not thrown.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.