Reputation: 2886
is there some way built in function/extension/tool to find all exception hidings/exception swallowing in C# solution(ASP.NET WebForms)n in VS2013.
Thanks
EDIT:
I have existing solution in which some programmers use hide/swallow exceptions(empty catch, catch only with some useless code). And I am looking for some way to find all these places in code, analyze them, and then fix them.
Upvotes: 3
Views: 976
Reputation: 59045
You can write some code using Roslyn to handle this pretty easily.
I actually wrote some code to do exactly that for a friend. It was my first attempt at using the Roslyn SDK, so my code is probably a terrible mess, but it was definitely functional.
static void Main(string[] args)
{
var result = Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseFile(@"..\..\Test.cs");
var root = result.GetRoot();
var exceptionNodes = FindCatchNodes(root);
foreach (var node in exceptionNodes)
{
var line = node.GetLocation().GetLineSpan().StartLinePosition.Line + 1;
if (IsTotallyEmptyCatch(node))
{
Console.WriteLine("Totally empty catch: line {0}", line);
}
if (JustRethrows(node))
{
Console.WriteLine("Pointless rethrow: line {0}", line);
}
}
}
static List<SyntaxNodeOrToken> FindCatchNodes(SyntaxNodeOrToken node)
{
var exceptions = new List<SyntaxNodeOrToken>();
var isCatchBlock = node.IsKind(SyntaxKind.CatchClause);
if (isCatchBlock)
{
exceptions.Add(node);
}
foreach (var result in node.ChildNodesAndTokens().Select(FindCatchNodes).Where(result => result != null))
{
exceptions.AddRange(result);
}
return exceptions;
}
static bool IsTotallyEmptyCatch(SyntaxNodeOrToken catchBlock)
{
var block = catchBlock.ChildNodesAndTokens().First(t => t.CSharpKind() == SyntaxKind.Block);
var children = block.ChildNodesAndTokens();
return (children.Count == 2 && children.Any(c => c.CSharpKind() == SyntaxKind.OpenBraceToken) &&
children.Any(c => c.CSharpKind() == SyntaxKind.CloseBraceToken));
}
static bool JustRethrows(SyntaxNodeOrToken catchBlock)
{
var block = catchBlock.ChildNodesAndTokens().First(t => t.CSharpKind() == SyntaxKind.Block);
var children = block.ChildNodesAndTokens();
return (children.Count == 3 && children.Any(c => c.CSharpKind() == SyntaxKind.OpenBraceToken) &&
children.Any(c => c.CSharpKind() == SyntaxKind.CloseBraceToken) && children.Any(c=>c.CSharpKind() == SyntaxKind.ThrowStatement));
}
Given this test file:
using System;
namespace RoslynTest
{
public class Test
{
public void Foo()
{
try
{
var x = 0;
}
catch
{
}
}
public void Bar()
{
try
{
var x = 0;
}
catch (Exception ex)
{
throw;
}
}
public void Baz()
{
try
{
var x = 0;
}
catch (Exception ex)
{
throw ex;
}
}
}
}
The output is:
Totally empty catch: ....\Test.cs: line 12
Pointless rethrow: ....\Test.cs: line 24
Pointless rethrow: ....\Test.cs: line 37
Upvotes: 9
Reputation: 4157
I don't know about the built-in methods. But you can write your own tool to find such places. Just regex all your files in solution and count catch and throw. There should be the same amount for each file :)
Upvotes: 1