What an exception is
What you'll learn:
- read the report of an unhandled exception and find the place of the error from it;
- catch exceptions with
tryandcatchblocks and pick a handler by class; - explain when
finallyruns, including afterreturn; - throw your own exceptions with
throwand release what an object holds withusing.

Picture an office building. On the fifth floor, a power socket starts to smoke. The employee doesn't put it out alone: they press the fire alarm button.
The signal travels from floor to floor: to the fourth, the third, and on down to the guard on the first. Someone along the way has to answer the alarm. If nobody does, the building is evacuated, and all work in it stops.
A program works in a similar way. The floors are method calls: Main at the bottom, above it the method it called, higher up the next call. This is the call stack from the theme on methods: the latest call lies on top.
When a method cannot do its job, it raises the alarm: it throws an exception. The exception goes down the chain of calls floor by floor: from a method to the one that called it, and on to Main. If nobody catches it, the program stops.
The analogy has a limit. In a building, the floors the signal passes keep working, while in a program every method on the exception's path is cut short.
You have met exceptions already. Each of them stopped the program:
FormatException:int.Parsegot a string with no number in it;DivideByZeroException: a whole number was divided by zero;OverflowException: a number overflowed insidechecked;IndexOutOfRangeException: an index went outside the bounds of an array;ArgumentOutOfRangeException:Substringwas asked for a piece past the end of a string;KeyNotFoundException: a dictionary has no such key;NullReferenceException: a member of an object was used throughnull.
Let's see what happens when the error occurs not in the top-level statements but in a method they called:
Console.WriteLine("Start"); // Start
int total = Sum("12", "ten");
Console.WriteLine(total);
int Sum(string a, string b)
{
int x = int.Parse(a);
int y = int.Parse(b); // ✗
return x + y;
}The path of an exception
Let's go through the program step by step:
Console.WriteLine("Start")printsStart.Sum("12", "ten")calls the method, and the top-level statements wait for its result.- In
Sum, the lineint x = int.Parse(a);puts the number12intox. int.Parse(b)cannot turn"ten"into a number and throws aFormatException.Sumis cut short on that line:return x + y;does not run, and there is no result.- The exception comes back to the line that called
Sum. Nobody catches it there either, soConsole.WriteLine(total)does not run. - The program prints an error report and stops.
The first line of the report:
Unhandled exception. System.FormatException: The input string 'ten' was not in a correct format.Below it come lines that start with at. They are the path of the exception along the chain of calls, from where it was thrown to the entry point <Main>$. First come methods of .NET itself, such as System.Int32.Parse.
Below them are your Sum marked line 8 and <Main>$ marked line 2: these are line numbers in the file. That is how you find the place of the error in a report. The name Sum appears there as <<Main>$>g__Sum|0_0: that is what the compiler calls a method declared among top-level statements.
An exception that nobody caught in the end is called unhandled. That is what the first words of the report say: Unhandled exception. Interviewers like to ask what happens to one: it passes through the whole chain of calls, and the program ends with a report.
An exception is an object
System.FormatException is the full name of a class: the namespace System and the name FormatException. At the moment of the error, .NET creates an object of this class and puts a message into it. The report shows both:
| Part of the report | What it means |
|---|---|
Unhandled exception. | nobody caught the exception |
System.FormatException | the class of the exception: what kind of error happened |
The input string 'ten' was… | the message: the details of this error |
Exception classes are linked by inheritance: all of them derive from one base class, Exception. The class tells what kind of trouble happened, and the message tells what exactly went wrong.
A compile error and an exception
A compile error is found by the compiler before the program runs. A program with one does not start at all, and the message carries a code like CS1002.
An exception happens while the program runs and depends on the data. The program with Sum("12", "ten") compiles without a single warning. The same program with Sum("12", "30") would run without errors and print 42. The compiler does not know what text will reach a and b, so this kind of error shows only when the program runs.
Common mistake
The task is to add up the numbers in an array of strings. The expectation is that the program skips the string "x" and prints 8:
string[] items = ["3", "x", "5"];
int sum = 0;
foreach (string item in items)
{
sum += int.Parse(item); // ✗
}
Console.WriteLine(sum);Unhandled exception. System.FormatException: The input string 'x' was not in a correct format.The program compiles, but it stops on the second element. The exception cuts short not one pass of the loop but the whole foreach and the whole program: Console.WriteLine(sum) is never reached. To skip such strings, you check them with int.TryParse from the methods theme, or you catch the exception.
Key points
- A method that cannot do its job throws an exception, and the exception travels back along the chain of calls to
Main. - Every method on that path is cut short: the lines after the place of the error do not run.
- An unhandled exception stops the program. The first line of the report names the class and the message, the
atlines the path and the line numbers. - An exception is an object of a class derived from
Exception, with a message inside.