I’ve seen this sort of pattern in code before:
//pseudo C# code
var exInfo = null; //Line A
try
{
var p = SomeProperty; //Line B
exInfo = new ExceptionMessage("The property was " + p); //Line C
}
catch(Exception ex)
{
exInfo.SomeOtherProperty = SomeOtherValue; //Line D
}
Usually the code is structured in this fashion because exInfo has to be visible outside of the try clause. The problem is that if an exception occurs on Line B, then exInfo will be null at Line D. The issue arises when something happens on Line B that must occur before exInfo is constructed. But if I set exInfo to a new Object at line A then memory may get leaked at Line C (due to “new”-ing the object there). Is there a better pattern for handling this sort of code? Is there a name for this sort of initialization pattern?
By the way I know I could check for exInfo == null before line D but that seems a bit clumsy and I’m looking for a better approach.
5
You should initialize exInfo before the try
block. In .NET you won’t leak any memory at Line C.
I’m going to try and make a concrete example out of your pseudocode, and see if that helps. Assume db.getList() runs some SQL and returns NULL if nothing found, a list if elements were found, and throws an exception on error.
List<String> stuff = new ArrayList<String>();
try {
stuff = db.getList("SELECT someColumn FROM someTable");
}
catch (SqlException e) {
log.error("Couldn't retrieve stuff!", e);
}
return stuff;
In Java and other garbage-collected languages, no memory would be leaked after your line C if you initialized the variable previously. The initial object would have no references associated with it and would be then eligible for garbage collection. This pattern allows you to keep code calling this code null-safe, since it will always return a valid List<>.
4
It’s a good idea for a variable to never contain an incorrect value, if at all possible. That way there’s no possible way, for example, for maintainers to later insert a bunch of statements between Line A and the try
block, then somewhere in there accidentally use exInfo
when it’s null
. The general solution when you’re tempted to initialize a value to null due to scope reasons is to break off the initialization code into its own function, so you would call:
var exInfo = createExInfo();
And createExInfo
would contain:
try
{
var p = SomeProperty;
return new ExceptionMessage("The property was " + p);
}
catch(Exception ex)
{
var exInfo = new ExceptionMessage();
exInfo.SomeOtherProperty = SomeOtherValue;
return exInfo;
}
1
I would refactor like this:
var p = null;
var exInfo = null;
try
{
p = SomeProperty; //Line B
}
catch (Exception ex)
{
exInfo = new ExceptionMessage("The property was " + p == null ? "foo" : "bar"); //Line C
exInfo.SomeOtherProperty = SomeOtherValue; //Line D
}
exInfo.BlahBlahBlah = "Blah";
How about creating class that has an event handler? Then initialize exInfo before initializing var p, which would guarantee that exInfo would not be null?