Avoiding exceptions

Posts   
 
    
clint
User
Posts: 150
Joined: 15-Nov-2005
# Posted on: 03-Mar-2007 00:15:01   

I keep reading in Microsoft documents and other documents that exceptions should be used for exceptional situations since they are expensive to throw. They recommend returning bools or error codes for common error situations. But LLBLGen entity validation seems to promote throwing exceptions for all errors.

I saw another thread where Otis and some other guy discussed this issue. Basically Otis said they had to throw exceptions during entity validation so the transaction can be rolled back.

It also appears that LLBLGen throws exceptions for stuff like a value being too large for the field.

Since it seems like LLBLGen is going to throw exceptions anyways, I figured I'd follow the Microsoft advice and avoid the exceptions in the first place. Which means the calling code needs to know what causes exceptions and check the data before saving to ensure that an exception won't be thrown.

For example, if you had a Person entity whose name field was required to be filled, I would add that as a check in the ValidateEntityBeforeSave() override. It would throw an ORMEntityValidationException if the name wasn't filled. But do any of you try to avoid the exception in the first place by adding a test in the code that calls DataAccessAdapter.SaveEntity() to check if the name is empty before calling save?

Walaa avatar
Walaa
Support Team
Posts: 14983
Joined: 21-Aug-2005
# Posted on: 05-Mar-2007 08:03:15   

You should place checks all of your layers (GUI, BL & DAL), to avoid exceptions. Yet an exception is very important as the last lineof defence.

You should have GUI validators, and BL checks. It's a best practice to design and code every layer as it is the only one doing checks/validation.

Early detected errors saves processing time.

PilotBob
User
Posts: 105
Joined: 29-Jul-2005
# Posted on: 05-Mar-2007 16:06:06   

clint wrote:

But do any of you try to avoid the exception in the first place by adding a test in the code that calls DataAccessAdapter.SaveEntity() to check if the name is empty before calling save?

I belive there is a validate() entity method that is for user use. You could write you code there and then in the ValidateBeforeSave() call that method like:

if ! this.Validate() throw new ApplicationOrOtherException();

Then from your UI code, before you did a save you could do:

if MyEntity.Validate() MyEntity.Save(); <-- or use adaptor, whatever.

BOb

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 06-Mar-2007 12:36:13   

It's a delegate discussion: using exceptions instead of error codes. LLBLGen Pro throws exceptions where it can't continue and what's in progress has to stop. That's basicly what's the rule of thumb we use to decide whether an exception should be thrown or not.

Now, you can stop logic with a return value as well, simply test on the return value, and if it's an error, stop your routine. However, that doesn't really work well in a system where a lot of objects take part in a process which takes multiple steps. In such a system, you simply want to have an exception so the execution ends up in a handler from which you can recover or give up.

The validation logic for example throws an exception because the value will otherwise always result in an exception later on, plus (and this is the main part) databinding code often only refuses to proceed if an exception occured.

With transactions, there's really no other way to stop them than to throw an exception, as otherwise you'll end up in return value hell, where you have to report upwards return values like what's done in COM which can get out of hand because you might want to add more info than just 'it failed', like which entity failed and where.

In these situations, an exception is a great thing to have because you simply throw it and the RESPONSIBLE routine will get it as the responsible routine was the one calling the throwing code (indirectly) anyway.

At that level, the routine should determine to give up or retry/recover.

However, as walaa said, try to avoid exceptions up front, by validation. This means that when a save action is started, you already know the data is correct to a level where you could test it to be correct (it might give up because it clashes with a unique constraint for example but that was out of your control at that point).

Frans Bouma | Lead developer LLBLGen Pro