Are validation errors exceptions?
I was discussing with a customer about the best way to design, code and use business validation logic. First of all, there were a number of decisions already made:
- Business entities will be represented as typed datasets
- There will be one data access logic components (dalc) per each business entity. The dalc will do CRUD operations
- There will be (roughly) one business logic component per business entity
- The business validation logic will be implemented in one method, Validate(), member of the business logic component
So, in general terms, we'll have: VoucherDalc, DsVouchers and VoucherManager. Now let's focus on the validation issue. As many validation errors could be detected in the DsVouchers dataset, a reasonable signature for Validate() is:
public ValidationError[] Validate(DsVouchers ds)
Where a ValidationError object (structure?) has enough information to describe the problem to the final user. The method is public so as to allow the UI logic to call Validate() when necessary. Furthermore, the business logic component (VoucherManager) will also be responsible for passing update requests to the data layer, so it needs this method:
public void Update(DsVouchers ds)
But, so that no invalidated data is sent to the data layer, Update() should call Validate(), for this reason a better signature (and implementation) for Update() is:
public ValidationError[] Update(DsVouchers ds) {
ValidationError[] errors = this.Validate(ds);
if (errors.Length > 0)
return errors;
...
}
But I don't like this because:
- Is it natural (from a business design point of view) that Update() returns a ValidationError array? Not really
- Programmers calling Update() may easily ignore the returned value, so errors are ignored!
That's why a better implementation could be:
public void Update(DsVouchers ds) {
ValidationError[] errors = this.Validate(ds);
if (errors.Length > 0)
throw new ValidationException(errors); // now we use an exception
...
}
Performance suffers because of the use of exceptions but we win:
-
No unnatural returns from Update()
-
Errors are harder to ignore (a very lazy developer can still do a try { ... } catch {} though)
-
If carefully written the ValidationException can travel thru physical layers
So, in spite of the general recommendation of using exceptions only for errors that happens outside the application control (e.g. printer not ready, server not available, disk full, ...) may be it's a good idea to use exceptions to report validation problems as part of the Update() method. Opinions?