James Jeffery
James Jeffery

Reputation: 12599

Try, Catch Problem

I've noticed this problem happening a lot in most things I do, so I'm thinking there must be a design pattern for this.

Basically if an exception is thrown, attempt to solve the problem and retry. If I place it in the try, all it will do is catch the exception, but I want to retry whatever it was doing and if it fails again, retry again a certain number of times.

Is there a common pattern for this sort of stuff?

Upvotes: 12

Views: 2005

Answers (9)

Dolph
Dolph

Reputation: 50720

Coding what others have already mentioned:

var success = false;
var attempts = 0;
var maxAttempts = 0;

do {
  attempts++;

  try {
    /* your code */
    success = condition;
  } catch(SuperciliousException e) {
    /* recover */
  }
} while(!success && attempts < maxAttempts);

Upvotes: 1

Mark Byers
Mark Byers

Reputation: 839264

Yes, it is quite common to have a loop with a number of retries where you break out of the loop on success. A couple of things:

You might want to add a delay before retrying so that you don't use up all your retries in just a few milliseconds before the temporary problem had time to fix itself.

If you eventually fail, you should throw the first exception you caught, not the last one. The second exception could be the result of failing to recover correctly from the first failure and might not help to debug the original problem.

Upvotes: 1

Jeeva Subburaj
Jeeva Subburaj

Reputation: 1921

check this SO answer.. hope that helps u

Cleanest way to write retry logic?

public static class RetryUtility
{
   public static void RetryAction(Action action, int numRetries, int retryTimeout)
   {
       if(action == null)
           throw new ArgumenNullException("action"); 

       do
       {
          try 
          {  
              action(); 
              return;  
          }
          catch
          { 
              if(numRetries <= 0) 
                  throw;  // Avoid silent failure
              else
              {
                  Thread.Sleep(retryTimeout);
                  numRetries--;
              }
          }
       } 
       while(numRetries > 0);
   }
}

Call

RetryUtility.RetryAction( () => SomeFunctionThatCanFail(), 3, 1000 );

Credit goes to LBushkin

Upvotes: 17

James
James

Reputation: 9985

This runs indefinately but it would be easy to add a loop counter to the while clause

    var solved = false;
    var tries = 0;

    while (!solved)
    {
         try
         {
            //Do Something
            solved = true;
         }
         catch
         {
             //Fix error
         } 
         finally
         {
              if(solved || IsRediculous(tries))
                 break;

              tries++;
         }
    }

Upvotes: 6

Nick Monkman
Nick Monkman

Reputation: 637

Are you sure exception handling is the proper methodology here? If you can "solve the problem" you can probably detect the error condition prior to calling the exception-generatiing code.

Exception handling is most natural for things which are truly exceptional. A failed Internet connection (as in the previous answer) is something that can be detected and handled before calling exception-throwing code.

Upvotes: 1

CaffGeek
CaffGeek

Reputation: 22074

Depends what you are trying, but typically you want to check for the possibility of an exception happening PRIOR to executing the code that could cause an exception.

For example, check that a file exists before accessing it, and create it (or whatever) if it doesn't.

Upvotes: 1

Seth Petry-Johnson
Seth Petry-Johnson

Reputation: 12085

Something like this, maybe:

int MAX_RETRIES = 5;
for (var attempt=1; attempt <= MAX_RETRIES; attempt++) {
    try {
        DoSomethingThatMightThrow();
    }
    catch (AnExceptionIKnowHowToHandle) {
        if (attempt < MAX_RETRIES)
             continue;

        throw;
    }
}

Upvotes: 1

DRapp
DRapp

Reputation: 48179

On some limited basis, you might want to put your try/catch into a loop, and force break if is ultimately successful. Such might be for internet access testing and you want user to have another attempt at connection.

Upvotes: 1

Gabriel Magana
Gabriel Magana

Reputation: 4536

try/catch inside a loop, with a counter for retries?

EDIT: And your requirement of "retry whatever it was doing," you need custom logic for that, how to retry varies wildly (ie, reopen a stream, recreate the object, pause for X milliseconds, etc...), so you need it's own try/catch inside a loop for every atomic operation.

By "atomic operation" I mean a set of related statements, such as read a file. The whole file read into memory might be an atomic operation, for example.

Upvotes: 1

Related Questions