For this second installment of Software Design Tip of the Fortnight I want to talk a little about exceptions. Exceptions in .NET provide an excellent means of handling errors. We all know not to use exceptions for flow control, but there are many other ways to abuse exceptions.
Abusing exceptions can be anything from throwing the base Exception class, to throwing more than just exceptions. But the most common abuse of exception handling is to simply suppress them. We have all seen applications that do something similar to:
SomeBusinessObject bo = SomeBusinessObject.LoadWithId(4); try{ bo.SomeIntValue = int.Parse(txtSomeTextField.Text); }catch{ //the value wasn't int... so ignore it. } bo.Save();
The problem with suppressing exceptions is that most components don’t just throw them for the fun of it, there is some underlying reason why the exception was thrown in the first place.
The above example appears innocent enough. Int32’s Parse method throws an exception if it cannot parse the input string. But what if in the future another developer decides that the business object’s SomeIntValue needs a certain business rules that limits the acceptable values.
public class SomeBusinessObject{ //other class code public int SomeIntValue{ get{ return _someIntValue; } set{ if(value < 0) throw new BusinessRuleException("Invalid value for SomeIntValue."); _someIntValue = value; } } }