.NET Academy

Reading errors and debugging

Tell compile errors, runtime exceptions and logic bugs apart, and track each one down.

10 min read

You will learn

  • Read compiler error codes and messages
  • Read an exception and its stack trace
  • Find logic bugs with small experiments
  • Use breakpoints in a debugger

Bugs are normal

Every programmer, at every level, spends a large part of their time finding and fixing mistakes. The skill isn't writing bug-free code — it's finding bugs quickly. That starts with knowing which of the three kinds you're facing.

KindWhen you find outExample
Compile errorBefore the program runsTypo in a variable name, missing ;, wrong type
Runtime exceptionWhile it runs — it crashesDividing by zero, index out of range, null
Logic bugMaybe never — it gives wrong resultsWrong formula, <= instead of <

Compile errors: read the message

The compiler tells you where (line, column), which rule (a code like CS0029) and what went wrong:

(3,13) CS0029: Cannot implicitly convert type 'string' to 'int'
(5,1)  CS0103: The name 'totl' does not exist in the current context
(7,22) CS1002: ; expected

Tips:

  • Fix the first error first. One mistake (like a missing brace) can cause a cascade of confusing follow-up errors.
  • Search the code. Searching "CS0029" finds the official explanation and examples.
  • In this course's editor, click an error to jump to its line; the red squiggles show the exact spot.

Runtime exceptions: read the type, message and stack trace

When something goes wrong while running, .NET throws an exception. Unhandled, it stops the program and prints something like:

Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Program.<<Main>$>g__CountPositives|0_0(Int32[] numbers) in Program.cs:line 6
   at Program.<Main>$(String[] args) in Program.cs:line 19

Read it in three steps:

  1. Type — IndexOutOfRangeException. The name often tells you the whole story.
  2. Message — what exactly happened.
  3. Stack trace — the chain of calls, most recent first. Find the topmost line in your code: here, line 6 inside CountPositives.

Exceptions you'll meet constantly:

ExceptionUsual cause
NullReferenceExceptionUsing a member of a variable that is null
IndexOutOfRangeExceptionArray index < 0 or >= Length
ArgumentOutOfRangeExceptionSame idea, for lists, Substring etc.
DivideByZeroExceptionInteger division by 0
FormatExceptionint.Parse("abc")
InvalidOperationExceptionCalling something at the wrong time (e.g. .First() on an empty list)
KeyNotFoundExceptionReading a missing dictionary key

You'll learn to handle exceptions with try/catch in Track 3.

Logic bugs: question your assumptions

The program runs, but the answer is wrong. Debugging is now detective work:

  1. Reproduce it with the smallest input that shows the bug.
  2. Predict what each step should produce.
  3. Observe what actually happens — print intermediate values:
foreach (int n in numbers)
{
    sum += n;
    Console.WriteLine($"n={n}, sum={sum}");   // temporary debug output
}
Console.WriteLine($"sum={sum}, length={numbers.Length}, avg={sum / numbers.Length}");
  1. Where prediction and observation first disagree, that's your bug.

Rubber duck debugging

Explain your code, line by line, out loud — to a colleague or a rubber duck. You'll often hear yourself say the wrong assumption.

Using a debugger

Printing works everywhere, but a debugger is far more powerful. In VS Code (with the C# Dev Kit), Visual Studio or Rider:

  • Click left of a line number to set a breakpoint (a red dot).
  • Press F5 to start debugging — the program pauses at the breakpoint.
  • Hover over variables, or look at the Variables panel, to see their current values.
  • Step Over (F10) runs the current line; Step Into (F11) enters the method being called.
  • A conditional breakpoint pauses only when a condition is true, e.g. i == 999.

Key takeaways

  • Compile errors: read the location and the CS code; fix the first one first.
  • Exceptions: read the type, the message, then the topmost stack trace line in your code.
  • Logic bugs: reproduce, predict, observe — print or inspect intermediate values.
  • Learn your debugger's breakpoints and stepping; it pays off immediately.

Exercise

This code compiles, but it's buggy. CountPositives crashes, and Average returns the wrong answer for some inputs. Run it, read the exception and the output, and fix both bugs.

Program.cs
Loading editor…

C# runtime not loaded

Hint 1

The exception says IndexOutOfRangeException. Which index does the loop reach on its last iteration? Valid indexes go up to Length - 1.

Hint 2

Average({ 1, 2 }) prints 1. Which kind of division happens when both sides are int?

Show solution
int CountPositives(int[] numbers)
{
    int count = 0;
    for (int i = 0; i < numbers.Length; i++)
    {
        if (numbers[i] > 0) count++;
    }
    return count;
}

double Average(int[] numbers)
{
    int sum = 0;
    foreach (int n in numbers) sum += n;
    return (double)sum / numbers.Length;
}

Console.WriteLine(Average(new[] { 1, 2 }));
Console.WriteLine(CountPositives(new[] { 1, -2, 3 }));

Quiz

4 questions · 3 correct to pass
  1. 1.Which kind of problem is "CS0103 The name 'totl' does not exist in the current context"?

  2. 2.In a stack trace, which line usually points to the code you should look at first?

  3. 3.The program runs without errors but prints the wrong total. What kind of bug is this?

  4. 4.What does a breakpoint do?

To complete this lesson

  • ○ Solve the exercise
  • ○ Pass the quiz (3/4 correct)