Skip to content
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

Rule S2221: "Exception" should not be caught when not required by called methods #458

Merged
merged 3 commits into from
Jun 22, 2017

Conversation

michalb-sonar
Copy link
Contributor

Fix #433

"id": "S2221",
"message": "Catch a list of specific exception subtype or use exception filters instead.",
"location": {
"uri": "Ember-MM\Ember.Plugins\PluginSectionHandler.cs",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the tests raises on this :)

try
{
(code)
}
catch
{
//TODO: Hmmm?
}

Copy link
Contributor

@Evangelink Evangelink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for the sake of curiosity, have you reviewed all new issues to be sure they do make sense?
Could you rename your PR to have a full name (like your first commit).

@@ -2233,7 +2233,7 @@
<value>misra,cert</value>
</data>
<data name="S2201_Title" xml:space="preserve">
<value>Return values from functions without side effects should not be ignored</value>
<value>Return values should not be ignored when function calls don't have any side effects</value>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not have been updated by your commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, not sure where it came from.

{
var caughtTypeSyntax = catchDeclaration?.Type;
return caughtTypeSyntax == null ||
semanticModel.GetTypeInfo(caughtTypeSyntax).Type.Is(KnownType.System_Exception);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure whether this could happen or not but you might want to check for null after the GetTypeInfo() call.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't happen, as it returns a struct. I've added more test cases.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok thanks for the clarification.

if (!c.IsTest() &&
IsSystemException(catchClause.Declaration, c.SemanticModel) &&
catchClause?.Filter?.FilterExpression == null &&
!IsThrowTheLastStatementInTheBlock(catchClause?.Block))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is the best heuristic. I am in favor of early exit so I would most probably not have the throw as the last statement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not ideal, but this is what fxcop does :)

Very likely because before exception filters it was a common thing to catch exception, do something if it is of particular type, otherwise rethrow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so let's keep it like this.

{
var catchClause = (CatchClauseSyntax)c.Node;

if (!c.IsTest() &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we supposed to ignore test classes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule is already quite noisy, so I think it is reasonable. Should I flag it in rspec?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that "the rule is quite noisy" is the right explanation, also I tend to think that it is as bad to do it in tests as in real production code. Most of the time if you have a unit test catching exception you will not have the right behavior (of course you could test that some method throws nothing at all but I am pretty sure 90% of the cases could use a specific exception type and the rest mark it as FP). So I would rather update the code than the RSPEC.
@valhristov WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll appreciate a verbal explanation because I am not sure what are you talking about :)

Copy link
Contributor

@valhristov valhristov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment, generally LGTM, can we somehow limit the positives more? E.g. did you review all of them?

}

return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be you should not use DescendantNodes() because it is recursive. I think, you only need the last statement in the block to be throw, hence you could probably use ChildNodes... In other words this should not be acceptable:

catch
{
    if (something)
    {
        throw;
    }
}

but this should be:

catch
{
    if (something) { ... }
    throw;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is exactly what I thought, but fxcop disagrees - first example is considered fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are cases when the exception is logged (via different mechanisms, so we cannot always tell) and some cases with "return" - but I'm not sure if the verbosity can be reduced. This rule is probably only useful in some contexts, and is not in sonar way.

@Evangelink
Copy link
Contributor

@michalb-sonar You need to rebase on master to fix the QA

@michalb-sonar michalb-sonar changed the title S2221 Rule S2221: "Exception" should not be caught when not required by called methods Jun 22, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants