asel
asel

Reputation: 1109

Can I avoid exceptions in C#, continuing code execution?

I have the following C# code. Whenever an exception is caught, say at line 1, I am never able to reach other lines (2, 3, 4, etc).

try
{
    line1
    line2
    ...
}
catch (Exception ex)
{
    ...
}

Is it possible, in C#, to say that if line 1 generates an exception, just continue on to the other lines (2, 3, 4, etc)?

Upvotes: 7

Views: 8857

Answers (13)

Daren Thomas
Daren Thomas

Reputation: 70324

You could create a SkipOnError method like this:

private SkipOnError(Action action)
{
    try 
    {
        action();
    }
    catch
    {
    }
}

Then you could call it like so:

try
{ 
    SkipOnError(() => /*line1*/);
    line2;
    line3;
} catch {}

Edit: This should make it easier to skip a given exception:

private SkipOnError(Action action, Type exceptionToSkip)
{
    try 
    {
        action();
    }
    catch (Exception e)
    {
        if (e.GetType() != exceptionToSkip) throw;            
    }
}

NOTE: I'm not actually suggesting you do this - at least not on a regular basis, as I find it rather hacky myself. But it does sort of show off some of the functional things we can now do in C#, yay!

What I would really do is this: Refactor line1 into a method (Extract Method). That new method should handle any foreseeable exceptions (if they can be handled) and thus leave the caller in a known state. Because sometimes you really want to do line1, except, maybe it's ok if an error happens...

Upvotes: 10

John Lechowicz
John Lechowicz

Reputation: 2583

You can isolate each line into a try-catch block, however that just wreaks of codesmell to me. If you are certain that the lines after line one do not throw exceptions, or need to be executed regardless of the exception and will not throw additional errors, you can add a finally block after the first catch. Example:

try{
  line 1;
}
catch(Exception exc){
  //Error handling logic here
}
finally{
  line 2;
  line 3;
  .
  .
  .
  line n;
}

Upvotes: 3

leppie
leppie

Reputation: 117240

You will need reifiable continuations to do that. The CLR and C# does not support that, and will probably never do so. :(

Upvotes: 1

Will Eddins
Will Eddins

Reputation: 13907

If it's possible to handle your exception and continue, you should localize your try/catch blocks.

try
{
  line1;
}
catch (ExpectedException e)
{
  // Handle your exception, prepare data for the next lines
  // Could you have prevented the exception in the first place?
}

try
{
  line2;
  line3;
}
catch (AnotherExpectedException e)
{
  // Maybe this exception you can't continue from. Perhaps log it and throw;
}

Remember that exceptions are exceptional. If an exception is thrown, something should have gone wrong. You should try to prevent the exceptions in the first place.

Upvotes: 0

Daniel Pokrývka
Daniel Pokrývka

Reputation: 73

try
{
    line1
    line2
    ...
}
catch (Exception ex)
{
    ...
}
finally
{
    if(line1ErrorOccured)
    {
        line2
        ...
    }
}

not given it too much thought though

Upvotes: 0

philsquared
philsquared

Reputation: 22493

As others have said, ensure first that "ignoring" the exception is what you really want to do. If it still is, and the syntactic overhead of all the try-catch's is too high, you could wrap it up with the execute-around idom.

I don't have time to sketch out all the code right now - but what you'd do is write a method that takes an anonymous delegate and executes it within a try-catch (maybe logging any exceptions, or filtering ones that are "ok"). Call this method something like tryDo. You could then write you code something like this:

tryDo( delegate(){ line1; } );
tryDo( delegate(){ line2; } );

It's still a little verbose, but then you don't want to make this stuff too easy. It's just enough overhead to make you keep wondering if it's the right thing to do :-)

Upvotes: 1

Josh Mein
Josh Mein

Reputation: 28645

just put a try catch around line1

try
{
    try
    {
        line1
    }
    catch (Exception ex)
    {
       ...
    }

    line2
    ...
}
catch (Exception ex)
{
    ...
}

Frederik is right though you really need to be careful when doing this. It should be used on a case by case basis. Only when you know that the process should continue should you use it. Otherwise you should handle the exception accordingly.

Upvotes: 5

Philippe
Philippe

Reputation: 4051

You can put the other lines in a finally clause, but that would be quite ugly, especially if these can throw exceptions as well...

You should recover from the first exception, and then carry on to the next line, wrapping each in a try/catch statement.

Upvotes: 1

Cylon Cat
Cylon Cat

Reputation: 7201

If there's code that you always want to be executed, even if an exception is thrown, even if the exception either doesn't get caught in the catch block, or the catch block re-throws or throws a new exception, it should go in the "finally" block:

try
{
  do(something);
}
catch (InvalidArgumentException ex)
{
  onlyDealWithOneExceptionType();
}
finally
{
  always.runs(no, matter, what);
}

Upvotes: 4

James
James

Reputation: 82096

As suggested, you should wrap the try catch around line1 in this particular example. However, for future note you should only really ever have conditions in your try catch block that you only want to be completed IF there are no exceptions.

Upvotes: 1

Brian
Brian

Reputation: 118865

You can always do

try 
{
   line1
}
catch (Exception ex)
{
}
line2
...

But there is nothing like a 'retry' keyword.

Upvotes: 1

Frederik Gheysels
Frederik Gheysels

Reputation: 56934

Exceptions should not be ignored. :)
They exists and are thrown for a reason: an exceptional situation has occured, a certain condition is not met, and I cannot continue working ...

It is possible to ignore exceptions, if you put a try / catch block around each line of code, but I don't think that you really want to do that ...

Upvotes: 16

Scott M.
Scott M.

Reputation: 7347

you can wrap just line 1 in a try catch block.

Upvotes: 2

Related Questions