Thursday, 23 May 2013

The Agony of a Defensive Programmer

By nature I'm a defensive programmer, a good example is whenever I use C++ I want to force wrapping of my classes as smart pointers, by making the constructors private and only giving a static factory create function, which returns a smart pointer wrapped copy of the pointer to the new class each time...

So, when I'm left to pick up the pieces after a non-defensive programmer is pains me immensely... Not least when the situation is an obvious like a file load.. Here's the gist of the problem, I'm not being specific, but lets assume:


if ( File.Exists(m_Filename) )
{
Load();
}
else
{
Create();
Save();
}

Now, if the file isn't there, you make a copy... And save it, whenever you come back you load it... "What's wrong with that?"

Well, the load function, lets take a look:

void Load ()
{
DeserialiseFile(m_Filename);
}

So, it just tries to read and deserialise the whole file?... yeah... and still not seeing the problem?

If you don't see the problem, a small part of me weeps for you... For the problems are many, and annoying, and mine to fix when you stroll off and leave this code as acceptable.

i. What if the file is corrupt?
ii. What if the file format changes?
iii. What if someone has saved a file with the same name?
iv. What is some sneeky so-and-so has saved a fake file there to try and force your system to do something strange?

All these problems, cause a crash of the attempt to DeserialiseFile, and so bring the program to its knees...

So what would I, the defensive programmer done?  Well, how about:

void Load()
{
try
{
DeserialiseFile(m_Filename);
}
catch (Exception l_e)
{
Output/LogError(l_e);
}
}

So, now the program doesn't crash, and you can detect out of date formats, or erroneous files, or corruption...

There are better solutions than this, but this isn't even my code, so I'm forced to do the bare-minimum to "fix" it, and to fix it I'm literally just catching & logging the problem, and then carrying on.

No comments:

Post a Comment