CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Brendan Tompkins [MVP]

Blog First. Ask Questions Later.

Validating Business Rules and Returning Errors

Today, I ran into a situation where I needed to validate some Business Rules (BRs) within a business object.  To do this, I needed to call into some secondary business layers to do some checking, and if a business rule failed, I needed to note “Why” and return this result back to the caller. This final caller in this case was client connecting to a Web-Service endpoint.  My problem arose because I needed to know two things, IF and WHY the BR failed.

At first glance, I thought I could just throw an exception, and catch it within my business tier, the exception itself would tell me the IF, and the exception's message the WHY.  I could then repackage a result object which would be returned to the web client caller.  I asked the CodeBetter guys what they thought, and was instantly reminded that Rule #1 is not to use exceptions to control program flow.  

Raymond Said :  You violate the primary rule of exceptions: do not use exceptions to control the flow of the program.  If you're expecting and exception to occur in that logic, I would let it propagate back up the call stack.  Just my opinion.  Some people do exactly what you are proposing and have no issues about it.  I personally don't like to see them used in that manner.

In fact, I knew this, but forgot that I had blogged about it over a year ago (and I thought blogs were supposed to help you remember ).  The big thing I learned is summed up by these two “almost rules” by Rico Mariani: Exception Cost: When to throw and when not to. (This is actually mentioned in the comments of Jeffrey’s recent post, Why are error return codes evil? - level 100.)

Almost Rule #1

When deciding if you should throw an exception, pretend that the throw statement makes the computer beep 3 times, and sleep for 2 seconds. If you still want to throw under those circumstances, go for it.

Seriously, people throw much too often, and for things that aren't really very exceptional at all. In fact, my own opinion is that the framework itself throws far more often than it should. The actual throwing of exceptions is sufficiently costly that I try to limit it to cases where I'm certain that less than 1 call in 1000 (99.9%) to a particular service will require an exception. This means throwing exceptions on things like invalid arguments to an API is probably just fine, but on the other hand throwing an exception due to invalid user input, or badly formatted text from an external system, could be a bad idea. Significant use of exceptions in business logic validation is more often a bad idea than a good one, so be careful out there.

Almost Rule #2

If you think it will be at all normal for anyone to want to catch your exception, then probably it shouldn't be an exception at all.

Again, my favorite consumer of exceptions is a generic exception handler at a fairly high level on the stack. Anything that fundamentally needs to be dealt with at a lower level should be looked at suspiciously. Often such a beast would fail the “only 1/1000” of the time test. Since doing control flow with exceptions is alot more expensive/confusing than other forms of control flow its best avoided if the special handling is commonplace.

What I like to see is general purpose logic for state cleanup, transaction abort, reset and retry. What I don't like to see is “downgrading” an exception into a return code, or routinely being able to “ignore” the exception and proceed. Those latter cases are usually a bad sign.

After reading this I realized that my original solution was a bad, bad idea.  So, what to do?  Remember I needed to know both the if and the why.   Returning two things is somewhat of a problem, since you can only return one thing from a method.  Jeffrey suggested the following:

Another option is to have the validate method return a collection of strings of errors.  If the collection is empty, there are no errors.

So, basically an empty versus filled collection would signify the IF and the collection text the WHY.  I asked him if he thought that this was somewhat of a code smell, since the IF is inferred, and Jeffrey replied with the following:

It would be a code smell in a high-level API, but if this was wrapped inside the method that returns your result object, then it wouldn't be exposed to the outside.  It's really up to you, but in that case, I'd name the method (GetErrors) or something like that.  Then it might be a more clear that no errors back means you can continue.

Okay, fair enough.  But it still not a perfect solution to this problem, IMO. I thought I’d post about this because its the kind of real-world coding problems you can run into when you try to do things the right way.  At the end of the day, I really had to choose the best of a bad set of options frankly – I created a result object that has a boolean member (succeeded) and a string (extra message).  My business calls return this object. Now, I’m not even sure if this is the best possible design.  Raymond has also suggested that there may be problems with this – for example, say you have an error message that indicates that the method failed with a true value for success. This can be fixed by making the boolean read only, based on some internal logic (like error message null) but then the message always has to indicate an error. 

-Brendan



Comments

BlackTigerX said:

that's kind of a common scenario that I am faced with, and I've always wondered what the best solution is, I go for the exceptions when the condition shouldn't happen (is exceptional) and when I need to stop any further processing because whatever failed needs to stop any further process... I wonder if there is some kind of pattern & practice for this scenario

on the other hand, I've seen the most horrid solutions to this problem, i.e. a guy had an array of, say 5 characters, he sends this array to the function that does the rules checking, and for every step that is failed, he puts an "X" on the corresponding position in the array, then when the function returns he checks the array for any "X", and then returns "error happened!" aaarrrgggh!!!
# October 14, 2005 6:25 PM

Blah said:

How about using the Notification pattern from Fowler?
# October 14, 2005 7:18 PM

Joshua Flanagan said:

I think you have to put Rico's advice in context with his role/background. If I remember correctly, he is completely focused on performance. In that context, performance becames the main motivation for design decisions.
I tend to agree more with Jeffrey Richter's advice on exceptions, which values object oriented cohesion and code readability over performance. (As an aside, it's very rare that Richter votes against performance - this is the guy that rants that foreach keyword is evil). ""Throw exceptions when the implicit assumptions of a method are violated." The idea is that if you do not (in theory) know how your classes will be used, you cannot decide for the consuming developer what is the right thing to do for their application. It is when you are the developer of the application and the consumed classes, and you see both sides, that you start to think that exceptions are being used for flow control.
You already seem to acknowledge that exceptions would be the cleaner, more obvious solution. Is performance an issue for your application, that you need to think of a more convoluted solution?
What if you handed off your business classes to another developer to use in their application? Does constantly checking a return code still make sense?
Of course, designing for reuse by other applications that may not ever exist makes about as much sense as being overly concerned with performance. Which solutions "feels" right?
# October 14, 2005 11:34 PM

John Papa said:

Hi Brendan, I was out at VSLive last week so I came back to a billion emails .... but I had some thoughts on this ...

I've often leaned towards creating a validation method (or full class if warranted) that handles all of my business logic validation. Thenassuming that I want to pool all of the violations I check my business rules and if one is violated, I throw a violaiton code and pretty message into a list to eb returned. The idea here is that I know these are not system exceptions but rather that they are business specific issues that need addressing. If the validation routine routine a list.count > 0 then the save method needs to do something with them (return them in a prettier/packaged format or something).

I have also created a validation class that has a property named "Passed" and a list of ValidationIssue classes which describe the business rule validaitons. Just a little more overhead with the classes, but much cleaner when all of your business rules follow the same approach.

Just some thoughts. Good luck to you!
# October 15, 2005 10:29 AM

Robert said:

I will never throw an exception unless the program can not continue gracefully.

Many business validation frameworks that i've developed use return codes for program flow errors. In my biz base class with a ReturnCodeCollection GetReturnCodes(), [XmlIgnore]bool IsValid {get;} and Validate(), Validating and Validated events fire before and after actual check, in case consumer wants to handle there.

Like many other frameworks, I use property attributes and reflection for all the data type (length, format), value type comparer, regular expression, and dynamic expression validation, to keep my junk data out.

It's a non-abtrusive paradigm, meaning it's up to the consumer to actually validate, otherwise nothing really happens, probably get a null back instead of an object. Much like the Asp.Net validators.
# October 15, 2005 11:18 AM

Sam said:

I commented on this very issue somewhere last week I think. It's a real shame MS doesn't just hand out a simple Validates base-class for this developers could use. Seeing this wheel getting reinvented over and over in .NET (out of necessity mind you) is a shame.

I think Jeremy is on the right track. It's basically the same way RoR's ActiveRecord does it. In ActiveRecord your business objects don't have properties so much as a property-bag. This property-bag is then validated with rules you define in the object. When you attempt to save an object, the rules are invoked and an exception is raise if they are violated. This ensures you can't just bypass them, but it's not the intended way to make use of them. Instead you access a method called "valid?" (in .NET you might want to call it "validate") that returns boolean. If the object is in an invalid state, you can access the "errors" collection to find out what rules were validated, on what members, and access some generated friendly messages if you choose.

Some sample code might look like this:

<code><pre>
customer = Customer.new(params[:id])
customer.attributes = params[:customer]

if customer.valid?
customer.save!
else
flash.now[:warning] = customer.errors.full_messages
end
</pre></code>

In c# that'd look something like this:

<code><pre>
Customer customer = (Customer) NHibernateSession.Get(Request.QueryString["id"]);
FormHelper.SetFromForm(customer);

if(customer.IsValid()) {
NHibernateSession.Save(customer);
} else {
ErrorsLabel.Visible = true;

ErrorsLabel.Text = "<ul><li>" +
customer.Errors.FullMessages.Join("</li><li>") +
"</li></ul>";
}
</pre></code>

Something like that anyways. Basically, the point is you require a valid state before saves, but you also have the opportunity for easy validation and friendly messages you can display to a consumer.

I suppose this violates a rule some people hold dear though: That objects should never be able to be in an invalid state. As a pragmatic matter I just don't see the merit in that, and trying to ensure it can require a lot of extra work for little practical benefit. So I'd recommend against it, but that may just be me.

Anyways, I think you're on the right track. The trick I think, is to create something reusable, flexible, and consistent; so you can keep your interaction with your validating business objects clean and transparent.
# October 16, 2005 3:57 AM

Brendan Tompkins said:

This is great stuff, Sam, I think the Is Valid? If not-check errors pattern would work in my case, and it would be cool for the framework to have an interface of base class. I just have to figure out if it makes sense to bake this logic into my classes, or if that will defeat the reusabiliity. However,, I still think you'd hit my problem at some point, when you had to call into another layer to do the validation. You'd need to know the if and why, and there's no elegant way to know both, except IMO to throw an exception...

Joshua:

I'd think that the most natural use of my validation method would be to throw and exception.... If the developer knows that it may throw a BR exception they can code the most likey flow, and handle the exceptional condition (BR Failure) using try/catch which is a very elegant and readable way to write code... But, almost everyone I hear from says no, this isn't a good idea... The way the code is now is using a result obejct with a boolean and a string.. It's working..
# October 16, 2005 9:03 PM

Ridge said:

I've been using the Notification pattern as described by Fowler, in brief it basically looks like:

class ServiceResult {
IList<ServiceError> ServiceErrors { get; }
bool HasErrors { get; }
AddError(ServiceError), Contains(ServiceError), etc.
}

class ServiceError {
string Message { get; }
Exception Exception { get; }
}

So in my service layer you end up with stuff like:

SomeReturnObject DoSomething(someObject, out serviceResult) {
ValidateSomeObject(someObject, ref serviceResult);
...
return new SomeReturnObject();
}

The calling code is a little clunky, so you could do:

ServiceResult serviceResult = new ServiceResult();
SomeReturnObject foo = DoSomething(myObject, out serviceResult);

if(serviceResult.HasErrors) {
HandleErrors(serviceResult);
}
else {
DoNormalStuff();
}

In the service layer class you could easily define the various types of errors that could be returned...

It's a toss up for me, validation doesn't seem to me to be necessarily exceptional, but at the same time the notification pattern isn't too different from return codes and is a bit of a hassle to deal with. That said, where it does seem to come into usefulness is from the point of view of a web service caller. Exceptions suck as a web service caller. Assuming you want to use the same service layer (not a web service) for both your applications/libraries and to service your web services it seems like the right way to go.

Assume you want a web service caller to add a new Customer object, customers have names and addresses and the like. So they pass in a Customer and the name doesn't meet the business validation *and* the address doesn't validate. They'd get an exception on the name, correct, resubmit, get an exception on the address, etc. With notification we can bundle all these validation errors up and they can be checked and corrected with one call...

I hope that's clear, it's past my bedtime.. :P
# October 16, 2005 10:31 PM

Marc Brooks said:

I applaud your decision to not use exceptions to handle this situation!

What I usually do for business objects is to have a Validate method that accepts a bool throwError, and returns a list of business rule violations.

What I do is have client/service code call Validate passing false for the throwError parameter. In this case, the Validate method returns a list of enumerated values of business rules. Since they are enumerate values, you can easily switch on the enumeration returned and act accordingly. Additionally the can very easily be localized such that the error message given to the user is driven by a resource lookup.

Now, if someone calls through to the Save method even in the presence of violations (or because they didn't call Validate), then I want to throw an exception, so I internally call Validate inside the Save method and pass true for the throwError parameter. When that error is thrown, the Exception.Data is first filled with all the enumerated business rule violations.

This strategy insures that validation messages are available when desired via the Validate method, and that attempts to save bad data are stopped via an exception no matter what business object is being saved and no matter what the call depth. Lastly, the reuse of the Validate method and using an enumeration to encode the business rules allows code to handle problems and error messages to easily be localized.
# October 16, 2005 11:37 PM

Marc Brooks said:

# October 17, 2005 1:24 PM

Sam said:

>> "However,, I still think you'd hit my problem at some point, when you had to call into another layer to do the validation."

I'm not sure I understand this bit.

If a BusinessObject calls another, then it's within-model, so since it's already coupled to the targets, it's ok for it to aggregate any potential errors into it's own error collection I think.

Truth be told though, I don't really do this. Because of RoR Components (think server controls... kinda... if you stretch ;-)), I just validate each object individually.

Maybe you're talking about the BusinessObject making a call to an "upper" layer. If so, I'd avoid that, and haven't found a case where it should be necessary, but there's always exceptions to every rule I suppose.

Maybe you're talking about a BusinessObject being consumed in an "upper" layer. If so, that's exactly what I was trying to describe (poorly apparently). The sample code I wrote is actually from a Controller in the MVC sense. The Controller is checking to see wether the object is valid, and if not, sticks the friendly error messages the object generates into the View.

Is that really a good idea? I admit, at first it may seem distasteful. When you can define validation like so though, it's actually rather clean:

<code><pre>
Customer < ActiveRecord::Base
validates_presence_of :name, :date_of_birth
validates_format_of: :ssn, :with => /\d{3}-\d{2}-\d{4}/, :message => 'format must be "XXX-XX-XXXX"'
validates_length_of :password, :min => 5
end
</pre></code>

This might result in messages such as:

"Name is required"
"SSN format must be \"XXX-XX-XXXX\""
"Password must be a minimum of 5 charcters long"

So the full_messages() method prepends the member name, makes it pretty, and generates a friendly message for you (though you can customize it).

If I were writing a .NET app right now, I think I'd definitely find it worth-while to try to emulate RoR's behaviour here. And since the source is free, it's probably not too incredibly difficult either. :-)

Either way, I think the hard part is keeping it simple. The above is (IMO) simple. Marc's example is, (IMO) not. Not that it might not work great, and not that it doesn't conceptually accomplish the same thing, but it does it with a lot more code, the coupling and complexity is much higher, and it breaks SoC to a much greater extent.

Nothing a little refactoring couldn't fix though of course.
# October 17, 2005 11:29 PM

Brendan Tompkins said:

"If a BusinessObject calls another, then it's within-model, so since it's already coupled to the targets, it's ok for it to aggregate any potential errors into it's own error collection I think."

Sam, yes, in my case this is exactly what's happening.. the issue is how to get the errors from the other business entity.. I only want to call into the validation routine once, for performance cosiderations, otherwise I'd just validate each rule individually, and if there's a failure, it'd be easy to dterermine what the failure was. Maybe this is a code smell on my part, but I wanted to call into the business obj once and validate a bunch of rules, and then know which if any rules were violated.

# October 18, 2005 2:36 PM

Sam said:

I'm still not sure what the issue is. I think I'm doing a crap job explaining how ActiveRecord works.

The good news is it occurred to me hammet has his own version of ActiveRecord based on NHibernate. If you're already using NHibernate even better!

Here's an explanation of the Validations: http://www.castleproject.org/index.php/ActiveRecord:Validation

There's no question that I would go with hammet's version instead of rolling my own if I were to work on another .NET app (and I'm sure I will again).

Calling into the validation isn't the expensive part. You're prepared at this point to interact with a database anyways I assume. So the cost of instantiating a few regexs or whatever is just not worth even thinking about. The problem with the sort of validation that ActiveRecord does is that some of it will issue queries on it's own. It's really the only way to do it (besides just catching the constraint violations of course, but that results in a try/catch style of flow, so that's different). Can you think about batching the queries for performance? Sure... if it actually becomes a problem, there's probably substantial gains to be had there. I really really doubt it will pose a problem though unless your database is already choking.

Anyways, enough about performance. :-) If you want one-call, you can have that. Just interject your own business rules into IsValid so the other models you need are also validated.

You know how all those custom controls call into base.render()? Same thing. No matter what you're going to have X number of validation calls fire off unless you start repeating your validators in multiple places, which is very bad IMO. So if you want to hide X2-X10, and have X1 call into all those, that's cool IMO. It couples the object X1 is validating to the objects X2-X10 validate more closely, but if that's a dependent relationship anyways, then that's not necessarily a bad thing. In fact, from a maintenance stand-point, it might allow other developers to grok the domain you're working in easier.

Anyways, check out hammet's work. Unless I misunderstood what you're trying to do, I think that should help out. And it's code that thousands of others are using, and it's already documented better than any code I tend to write myself ;-), so if you're like me that way, that's a huge plus I think.
# October 23, 2005 1:04 AM

Brendan Tompkins said:

Ha Sam, you're probably just smarter than me. :)

I think much of the my confusion here may be due to the fact that I'm validating a "message" that's coming into a wse service, and I'm not thinking OO. I don't really want to have any code in the message class, and I'm passing it around to validating services within my framework. These services I want to be reusable.

I think your point is well taken as well, concerning perf, I did check out ActiveValidation too. It think if I'm to design this stuff for max reuse, I should do each rule validation separately, then if I do create an object with a Validate, IsValid, etc, this will plug right in.

# October 27, 2005 4:27 PM

Raza said:

Hi Brendan,

This comment is regarding your post what works and what not .

I have been using a DAO pattern crafted by Eric . The problem is that how do you handle folloiwing things using business objects

1) You want to update an object and its only 1 bit that you want to update but in order to update it you have to load the object first and then modify value and then save. There goes an extra database call.

2) Where are good sample codes i can see for different patterns?

Thanks a lot.
# October 28, 2005 10:36 AM

Sam said:

Somehow I doubt that Brendan ;)

Anyways, good luck!
# November 2, 2005 10:49 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Brendan Tompkins

Brendan has been programming with .NET since the first public beta and is owner and operator of Port Technology Services, a consultancy company providing .NET application development services to the Maritime industry. In July, 2007, he was awarded the Microsoft MVP award for ASP.NET. He's also a proud co-founder of failed .COM startup Intrinsigo, and has had a hand in the failure of numerous other businesses. He currently runs CodeBetter.Com and Devlicio.us, and lives in Norfolk, Virgina with his wife Tiara and son Ian.

View Brendan's profile on LinkedIn

Check out Devlicio.us!

Our Sponsors

Free Tech Publications