Handling exceptions and executing code if one was found

I have this code:

try
{
Console.WriteLine("Input number {0}", i + 1);
}
catch (Exception ex)
{
if (ex is ArgumentException)
{
Console.WriteLine("The input number wasn't in the alowed range. Please try again.");
}
else if (ex is FormatException)
{
Console.WriteLine("The input isn't an integer number. Please try again.");
}
else
{
Console.WriteLine("An unknown error occured. Please try again.");
}

i--;
}


I am wondering if there is a better way to do this - catch all exceptions and handle them and then, if any exception was caught, I want to reduce i by 1.

• you can use different catch blocks for different type of exceptions – Selman Genç Sep 4 '14 at 14:05
• I don't think you understood, I want to be able to catch all exceptions and handle them, BUT then have a code that is executed after all catch-es and only if one of them was entered. – frostblooded Sep 4 '14 at 14:08
• So you want i-- to happen only if an exception is caught, or you want it to happen regardless? – eddie_cat Sep 4 '14 at 14:10
• Only if an exception was caught :) And it works the way I did it, but I was wondering if there was a better way to do it. If there is a special operator to do it or something like that. – frostblooded Sep 4 '14 at 14:11
• This looks fine to me. – eddie_cat Sep 4 '14 at 14:13

So I'm assuming that all of this code is in a for loop, and that for loop is incrementing i as it's loop statement.

What you can do here is not unconditionally increment i in each iteration of the loop, and instead only increment i if you're able to read in the number successfully:

for (int i = 0; i < 10; )
{
try
{
Console.WriteLine("Input number {0}", i + 1);
i++;
}
catch (ArgumentException)
{
Console.WriteLine("The input number wasn't in the alowed range. Please try again.");
}
catch (FormatException)
{
Console.WriteLine("The input isn't an integer number. Please try again.");
}
catch (Exception)
{
Console.WriteLine("An unknown error occured. Please try again.");
}
}


However, for this case I'd say that there's an option that's better still.

What you should really do is, rather than having a method try to get another value from the user and possibly failing and possibly succeeding and needing to be called again, create a method that keeps asking the user for a value until it gets a valid one. This logic is far easier to implement at that scope than it is to try to continually add more iterations to the loop.

Once you create a method that will always get a valid value, trying as hard as it needs to:

public static int ReadNumber(int start, int end, int iteration)
{
while (true)
{
Console.WriteLine("Input number {0}", iteration + 1);
int n;
Console.WriteLine("The input isn't an integer number. Please try again.");
else if (n < start || n > end)
Console.WriteLine("The input number wasn't in the alowed range. Please try again.");
else
return n;
}
}


(Also note the use of conditional checks to determine if the user input is valid, rather than using exceptions for non-exceptional control flow.)

Now our loop is dead easy:

for (int i = 0; i < 10; i++)
{
int number = ReadNumber(start, end, i);
}

• Your answer makes a lot of sense and I like it. Thanks! – frostblooded Sep 7 '14 at 10:59

You could set a bool indicating if an exception was caught. I see no superiority in this way, but it exists. You might also consider catching these in seperate catch statements:

var wasCaught = false;
try
{
Console.WriteLine("Input number {0}", i + 1);
}
catch (Exception ex)
{
wasCaught = true;
if (ex is ArgumentException)
{
Console.WriteLine("The input number wasn't in the alowed range. Please try again.");
}
else if (ex is FormatException)
{
Console.WriteLine("The input isn't an integer number. Please try again.");
}
else
{
Console.WriteLine("An unknown error occured. Please try again.");
}
}
if (wasCaught)
{
i--;
}