Home > Software design >  Program not catching IndexOutOfRangeException
Program not catching IndexOutOfRangeException

Time:01-17

I'm following an old YouTube guide for C# learning and I'm stuck on one of the challenges for error handling.

class Program
{
    static Board myBoard = new Board(8);

    public static Cell setCurrentCell()
    {
        int currentRow, currentColumn;
        // get x and y coordinates from the user. return a cell location
        Console.Write("Enter a current row number: ");

        while (true)
        {
            try
            {
                currentRow = int.Parse(Console.ReadLine());
                break;
            }

            catch (FormatException)
            {
                Console.Write("Input has to be a number, try again:");
            }
            catch (IndexOutOfRangeException)
            {
                Console.WriteLine("Input was out of range, try a number between 0 and 8.");
                Console.Write("Please try again: ");
            }
        }


        Console.Write("Enter the current column number: ");
        while (true)
        {
            try
            {
                currentColumn = int.Parse(Console.ReadLine());
                break;
            }
            catch (FormatException)
            {
                Console.Write("Input has to be a number, try again:");
            }
            catch (IndexOutOfRangeException)
            {
                Console.WriteLine("Input was out of range, try a number between 0 and 8.");
                Console.Write("Please try again: ");
            }
        }
      }
        return myBoard.theGrid[currentRow, currentColumn];
    }
}

I'm trying to catch an error if user enters a number out of bounds but the catch just skips over it and then throws the error anyways. what am I doing wrong here?

CodePudding user response:

Following Int32.Parse method documentation – exception type IndexOutOfRangeException is not handled here.

If you want to check that value is less than Int32 min value or greater than Int32 max value, you should catch OverflowException.

CodePudding user response:

IndexOutOfRangeException is throw by an attempt to access an indexable collection (arrays, List<T>, anything that implements IList<T>, etc.) using an invalid index - less than 0 or greater than or equal to the collection size.

Here's the first try block in your code:

try
{
    currentRow = int.Parse(Console.ReadLine());
    break;
}

Nothing in that block is attempting to index a collection, so we wouldn't expect IndexOutOfRangeException to be thrown. In fact there are only two things in there that can throw an exception at all (int.Parse and Console.ReadLine), neither of which can throw IndexOutOfRangeException under any circumstances.

There's only one line in your code that performs an indexing operation on a collection and that's the final return statement... which is not contained in a try...catch statement.


What you're trying to achieve is to range-check the entered values. There are a couple of ways to do this, but if you insist on using exceptions (which I wouldn't do, but you're learning I guess) then you can check the inputs by attempting to index the board's theGrid array after the parse in each try block like this:

try
{
    currentRow = int.Parse(Console.ReadLine());
    var test = myBoard.theGrid[currentRow, 0];
    break;
}

And for currentColumn:

try
{
    currentColumn = int.Parse(Console.ReadLine());
    var test = myBoard.theGrid[0, currentColumn];
    break;
}

If the entered value (currentRow or currentColumn) is out of bounds then this will throw the IndexOutOfRangeException as expected. (The 0 in the other index is guaranteed to not throw unless the row/column count is 0.)

  • Related