hungryMind
hungryMind

Reputation: 6999

Catch and Continue

I want an extension method or generic method where I want code execution to continue even there is some exception and keep recording the exceptions in a list. This is an example what I tried

    public void ValidateName()
    {
        if (_customer.Name.Length < 5)
            throw new Exception("shortname");
    }
    public void ValidateAge()
    {
        if (_customer.Age < 5)
            throw new Exception("short age");
   }
    internal void Validate()
    {
        this.CatchAndContinue(delegate()
        {
            this.ValidateName(); // throws exception and add to list
            this.ValidateAge(); // but this should also execute
        });
    }
    public void CatchAndContinue(Action action)
    {
        try
        {
            action();
        }
        catch (Exception ex)
        {
            exceptions.Add(ex);
        }
    }

For current class I can pass exceptions to ValidateName and ValidateAge method, but I want if we can do the way I want, with little change in validate() method body. I know semantically it sounds weired but I need lot of places to do this. Or if there is something better to achieve it

EDIT

This validation is simple example, not in all scenerio it will be validator only. By the way in this case I want to provide UI the list of errors and why throw, because when model constructed from DB (due to wrong data in DB) such objects should not be created. These are just examples of concern

Upvotes: 0

Views: 514

Answers (3)

Matthew
Matthew

Reputation: 25763

Yield / return may be useful to you.

http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx

Does it have to be exceptions?

To clarify:

internal IEnumerable<string> Validate()
{
    if( _customer.Age > 5 ) { yield return "Too Old"; }
    if( _customer.Name.Length < 3 ) { yield return "Not enough name characters"; }
}

// using it
IEnumerable<string> errors = myCustomer.Validate();
if( errors.Length > 0 ) {
    // uh oh, print out the errors!
    foreach( string error in errors ) {
        MsgBox(error);
    }
}

Upvotes: 0

jason
jason

Reputation: 241641

Don't use exceptions for control flow.

Instead, your validate method should return a bool, and let the client of the validate method decide what to do. One step beyond that is return a ValidationResult with a ValidationStatus property that indicates success or failure and a Message property that records the reason that validation failed.

Upvotes: 3

Mrchief
Mrchief

Reputation: 76218

Instead of throwing exceptions in the Validate methods, I would add to the exceptions list and return a bool value indicating success/failure (return part is optional, add it only if you care about the status of validation).

Something like:

public void ValidateName()
{
    if (_customer.Name.Length < 5) {
        LogValidationFailure("shortName");  // you can add more params if needed
        return; // or return false if you need it
    }

    // do normal business here
}

Not only is this cleaner, it is better performing since try/catch and exception throwing are expensive.

Upvotes: -1

Related Questions