25

I want to execute the code in the try block again after an exception is caught. Is that possible somehow?

For Eg:

try
{
    //execute some code
}
catch(Exception e)
{
}

If the exception is caught I want to go in the try block again to "execute some code" and try again to execute it.

Dmitrii Lobanov
  • 4,897
  • 1
  • 33
  • 50
Infant Dev
  • 1,659
  • 8
  • 24
  • 48
  • no, not a built-in standard way, but you can build your own – John Pick Feb 14 '12 at 05:11
  • possible duplicate of [Try/Catch exception continue from line that caused the exception](http://stackoverflow.com/questions/7125352/try-catch-exception-continue-from-line-that-caused-the-exception), [Try-Catch and "Continue" - is this possible?](http://stackoverflow.com/questions/6146248/try-catch-and-continue-is-this-possible), [Catch and Continue](http://stackoverflow.com/questions/7113929/catch-and-continue) – Cody Gray - on strike Feb 14 '12 at 05:17
  • 1
    @SunilKumarBM useful when making a call to a dodgy website/webservice which times out frequently or even throws 500 errors. – SynXsiS Feb 14 '12 at 05:18
  • 2
    Also known as: **Hey, how can I use `On Error Resume Next` in C#?** – Cody Gray - on strike Feb 14 '12 at 05:18
  • Have you tried putting it inside a while loop? – NYC Canuck Feb 14 '12 at 05:12

9 Answers9

48

Put it in a loop. Possibly a while loop around a boolean flag to control when you finally want to exit.

bool tryAgain = true;
while(tryAgain){
  try{
    // execute some code;
    // Maybe set tryAgain = false;
  }catch(Exception e){
    // Or maybe set tryAgain = false; here, depending upon the exception, or saved details from within the try.
  }
}

Just be careful to avoid an infinite loop.

A better approach may be to put your "some code" within its own method, then you could call the method from both within the try and the catch as appropriate.

ziesemer
  • 27,712
  • 8
  • 86
  • 94
9

If you wrap your block in a method, you can recursively call it

void MyMethod(type arg1, type arg2, int retryNumber = 0)
{
    try
    {
        ...
    }
    catch(Exception e)
    {
        if (retryNumber < maxRetryNumber)
            MyMethod(arg1, arg2, retryNumber+1)
        else
            throw;
    }
}

or you could do it in a loop.

int retries = 0;

while(true)
{
    try
    {
        ...
        break; // exit the loop if code completes
    }
    catch(Exception e)
    {
        if (retries < maxRetries)
            retries++;
        else
            throw;
    }
}
SynXsiS
  • 1,860
  • 10
  • 12
8
int tryTimes = 0;
while (tryTimes < 2) // set retry times you want
{
    try
    {
        // do something with your retry code
        break; // if working properly, break here.
    }
    catch
    {
        // do nothing and just retry
    }
    finally
    {
        tryTimes++; // ensure whether exception or not, retry time++ here
    }
}
David Smith
  • 893
  • 2
  • 9
  • 19
  • What if I want to `throw` an `Exception` if the 2nd `try` fails? Should I need another `catch` block for that? Would appreciate if you can share the syntax. – Heike Mar 20 '19 at 15:47
  • If you want throw exception, it may be easy. just write in catch (Exception ex) { if (tryTimes == 2) throw ex; } – David Smith Mar 22 '19 at 16:06
4

already answered in these (and other) links

Better way to write retry logic without goto

Cleanest way to write retry logic?

How can I improve this exception retry scenario?

Community
  • 1
  • 1
Mickey Perlstein
  • 2,508
  • 2
  • 30
  • 37
2

There is another way to do it (though as others have mentioned, not really recommended). Here's an example using a file download retry to more closely match the retry keyword found in Ruby in VB6.

RetryLabel:

try
{
    downloadMgr.DownLoadFile("file:///server/file", "c:\\file");
    Console.WriteLine("File successfully downloaded");
}
catch (NetworkException ex)
{
    if (ex.OkToRetry)
        goto RetryLabel;
}
Bill
  • 25,119
  • 8
  • 94
  • 125
  • 3
    Seems a lot more clear than recursion or infinite loops to solve this particular problem. – Bill Feb 14 '12 at 05:36
  • 1
    Unfortunately, that's exactly what you potentially accomplished here - an infinite loop. If the exception occurs, and nothing is done to resolve the underlying cause, there is no retry counter or such to stop the loop. The `ex.OkToRetry` check might be a start to this, but it isn't clear as to if or where this would ever be set differently between `true` and `false`. – ziesemer May 20 '13 at 20:45
  • 3
    @ziesemer - the same could be said for your example which got accepted as the answer. – user1021726 Feb 25 '14 at 12:16
1

I know the community opinion about goto, but this is a case where I would (and do) use it. One of my applications runs a BackgroundWorker which populates an ObservableCollection. While the BackgroundWorker is running and the ObservableCollection is being populated, I allow some other functionality through the UI, but I needed to base some logic on the count of the ObservableCollection at a point in time. So I did this:

long resultCount;           
try_again:
try
{
    //This statement sometimes fails because ocResultList is volatile
    //while the BackgroundWorker is running

    resultCount = <ClassName>.ocResultList.LongCount();
}
catch
{
    goto try_again;
}

if(resultCount...)
{
    //do something
}

Does exactly what I want - and no spaghetti code

Mureinik
  • 297,002
  • 52
  • 306
  • 350
RicPlouffe
  • 11
  • 2
  • Welcome to Stack Overflow! This answer doesn't seem different enough from the other proposed goto solutions already provided. Including an answer with a unique change for your situation that doesn't apply to the question is generally not helpful to others. – siva.k Aug 28 '21 at 04:49
0

What's wrong with the ole goto?

 Start:
            try
            {
                //try this
            }
            catch (Exception)
            {

                Thread.Sleep(1000);
                goto Start;
            }
I Stand With Russia
  • 6,254
  • 8
  • 39
  • 67
0

Try this:

try {  
  for (var i=0; (i < t && condition) || i === 0; i++) {
    //t is how many times you want the code to run.
    //condition should be true when there is an error.
    //The code you want to execute multiple times if it fails.
  }
} catch (e) {
  
  //The code you want to execute if the code still runs into an error after being repeated multiple times.
  
}

So, the code will run at least once. The condition should be true when the code results in an error, so the code will keep running until i = t, or the condition is false. If you want to execute some code after the first error, you can use if (i > 0), or if (i === 1) to do so.

Flyson
  • 1
  • 1
  • 2
0

This should work:

count = 0;
while (!done) {
  try{
    //execute some code;
    done = true;
  }
  catch(Exception e){
  // code
  count++;
  if (count > 1) { done = true; }
  }
}
Richard Rhyan
  • 203
  • 1
  • 6
  • 17