debugging
exceptions
software development
programming tips
error handling

Don't stop debugger at THAT exception when it's thrown and caught

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

A debugger that stops on every thrown exception quickly becomes unusable in codebases where exceptions are part of normal control flow or framework internals. The right fix is usually not to stop ignoring exceptions entirely. It is to stop breaking on the specific exception type when it is thrown and caught, while still breaking on unhandled exceptions that represent real failures.

Understand the Break Modes First

Most debuggers distinguish between at least two useful moments:

  • first chance or thrown: break as soon as the exception is raised
  • unhandled or user-unhandled: break only if the exception escapes normal handling

That distinction matters because many libraries intentionally throw and catch exceptions internally. If your debugger breaks at the "thrown" stage for those routine cases, you lose signal in a flood of noise.

A small example:

csharp
1using System;
2
3class Program
4{
5    static void Main()
6    {
7        try
8        {
9            int.Parse("not-a-number");
10        }
11        catch (FormatException)
12        {
13            Console.WriteLine("Handled as expected");
14        }
15    }
16}

If the debugger breaks on every thrown FormatException, this perfectly valid flow becomes annoying to step through.

Visual Studio: Disable "Break on Thrown" for That Exception

In Visual Studio, the usual fix is in the Exception Settings window.

The practical steps are:

  1. open Debug > Windows > Exception Settings
  2. search for the exception type, such as FormatException
  3. clear the Thrown checkbox for that type
  4. leave unhandled breaking enabled if you still want real failures to stop the debugger

This keeps the debugger from breaking on the routine thrown-and-caught case while still surfacing exceptions that escape handling.

The useful mindset is: change the rule for one noisy exception type, not for the entire runtime unless you have a very good reason.

Why Not Disable All Exception Breaking?

Because exceptions are still one of the fastest ways to catch real bugs. If you globally stop breaking on everything, you lose visibility into:

  • unexpected nulls
  • configuration failures
  • database or network errors that were not handled correctly
  • bugs hidden inside broad catch blocks

So the goal is selective tuning, not total silence.

Prefer Fixing Code Smells Over Hiding Them

Sometimes a noisy exception is a debugger problem. Sometimes it is a design problem.

If your code throws exceptions constantly in normal hot paths, the better fix may be changing the code to use a non-exception API.

For example, prefer int.TryParse over intentionally triggering FormatException repeatedly:

csharp
1using System;
2
3class Program
4{
5    static void Main()
6    {
7        if (int.TryParse("42", out var value))
8        {
9            Console.WriteLine(value);
10        }
11    }
12}

This is easier on both the debugger and runtime performance.

Conditional Tuning Helps in Large Applications

In a large application, one exception type may be noisy in one area but critical in another. In that case, do not treat debugger settings as the only tool.

Other useful techniques include:

  • adding targeted logging in the catch block
  • setting breakpoints near the code you actually suspect
  • using conditions or filters on breakpoints
  • narrowing the exception settings only to the types that are currently flooding the session

The point is to recover signal, not to guess blindly.

A Practical Debugging Strategy

A good working strategy is:

  1. keep breaking on unhandled exceptions
  2. keep breaking on thrown exceptions for types you are actively investigating
  3. turn off Thrown only for the specific caught exception types that are proven noise
  4. revisit those settings later instead of letting them accumulate forever

That keeps the debugger useful without turning it into a random interruption generator.

Common Pitfalls

The biggest mistake is turning off all exception breaking because one library is noisy. That usually hides bugs you actually care about.

Another mistake is forgetting that a caught exception can still indicate a design problem. If something throws thousands of times per second and gets caught every time, the debugger setting is not the only issue.

Developers also often confuse "thrown" with "unhandled." A debugger break at throw time does not mean the application would have crashed.

Finally, do not tune the debugger and then forget the change exists. A disabled exception breakpoint that made sense today may hide an important bug next month.

Summary

  • The right fix is usually to stop breaking on one noisy caught exception type, not all exceptions.
  • Keep unhandled exception breaks enabled so real failures still surface.
  • In Visual Studio, clear the Thrown checkbox for the specific exception in Exception Settings.
  • Prefer non-exception APIs such as TryParse when exceptions are part of routine control flow.
  • Use debugger tuning to improve signal, not to hide bugs wholesale.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.