We were asked to review a client application's code that involved ~1.5 million lines of code. The application has major stability and experiences frequent crashes and we are assigned the task of finding the root cause of such issues by doing a manual static code review. The goal is to prevent exceptions. It is not our goal to handle them better once they've occurred.
I have two examples below to illustrate defensive programming to prevent an exception: in the case of non-mandatory logic, and mandatory logic.
First example (non-mandatory logic): Defensive coding (the "if" condition in block 2) precedes usage of "obj". If "obj" is null, then the "if" condition skips the logic that would otherwise cause an exception. We may have instances in the code where the "if" condition doesn't exist - and it should be added to prevent an exception. We want to know the extent (effort) to which we should be adding this defensive logic.
2nd example (mandatory logic): In the second example, where the "if" condition checks for null (block 3), it is not valid to skip the logic because the logic is mandatory. In this case, the "if" condition must throw an exception. This defensive logic will not improve stability: an exception will be raised whether due to the null reference exception or due to the "if" condition throwing an exception.
We have been asked to find patterns in code which result in exceptions being thrown i.e. why the object did not get set - the problem is in the logic in block 1. (in this example: because it gets set only when SomeCondition is not false).
bool someCondition = false;
DataSet obj = null;
/*** Begin block 1 ***/
if(someCondition)
{
obj = new DataSet();
//Fill the obj with data
Populate(obj);
}
/*** End block 1 ***/
/*** Begin block 2 ***/
//Perform some non-mandatory logic
//defensive coding
if(obj != null && obj.Tables["Employee"] != null && obj.Tables["Employee"].Rows[5] != null)
{
DataRow row1 = obj.Tables["Employee"].Rows[5];
row1["FirstName"] = "Bob";
}
/*** End block 2 ***/
/*** Begin block 3 ***/
//Perform mandatory logic
//defensive coding
if (obj == null && obj.Tables["Employee"] == null && obj.Tables["Employee"].Rows[5] == null)
throw new Exception("Object obj cannot be null");
DataRow row2 = obj.Tables["Employee"].Rows[5];
row2["Role"] = "Manager";
/*** End block 3 ***/
We are doing a manual review of the code, but it is a huge ASP.NET MVC application which talks to backend WCF services and we are struggling to find patterns. Is it possible to do something other than manually? Are there any tools that can help us find such patterns.