Tuesday, December 10, 2013

Inheriting Someone else's Code

One of the major issues in development is what to do with the previous programmer's code. Usually it begins with the naming convention, this is easily solved - get used to it.
The following issue is the separation, or lacking of it, to different files and projects. While being a little nuisance, it's a "don't touch unless you have to".
The major issues arise when coming to fix a bug. What calls what? Which event comes first? What function threw the exception? All of those questions can be answered easily when you wrote the code, though it might take time to refresh your memory when it's an old piece. When it's not your code - spell trouble.
The easiest solution is using the debugger. There are 2 issues with the debugger:
1. Race conditions hardly ever happen when the debugger is attached.
2. Most of the clients I had didn't want the debugger, didn't allow it, and in some cases looked at it as trying to steal their data.

That's where logs come in handily. All you have to do is select the logging method (personally I prefer NLog, but there are many more libraries out there), and add the log lines.
After practicing logging for a long time I reached the conclusion that a some guidelines are needed. Mainly because no one really needs all the logs all of the time, normally you'll need only the errors, sometimes the warnings too. The lower levels are only used when trying to figure out what causes a certain behaviour.
So here are the guidelines (based on NLog):
1. Fatal - errors that forces the application to shutdown. I'm using it in the global trap, the global threaded trap, and when the application's initialization phase didn't complete successfully.
2. Error - anything that failed to execute correctly without an expected explanation. By expected explanation I mean invalid input data, known erroneous response from service and etc.
3. Warn - anything that failed to execute correctly with an expected explanation.
4. Info - any call to a public method, with the relevant parameters (i.e. username, but not the user's password).
5. Debug - Before entering any "interesting" method, and at the end of each method. By interesting I mean anything that might look like a potential problem to the programmer. For the debug pass EVERYTHING, in some cases even the passwords. When you're forced to use the debug, you have a real bug lurking out there and you must catch it ASAP.