.NET exceptions
application development
error handling
software development
programming tips

Which built-in .NET exceptions can I throw from my application?

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

You can absolutely throw built-in .NET exceptions from your own code. The key is to choose the type that accurately describes the contract violation or invalid state that occurred, rather than picking an exception just because the name looks close enough.

Good Built-in Exceptions for Application Code

Several built-in exception types are designed for ordinary application-level validation and state checks.

Common examples include:

  • 'ArgumentException'
  • 'ArgumentNullException'
  • 'ArgumentOutOfRangeException'
  • 'InvalidOperationException'
  • 'NotSupportedException'
  • 'ObjectDisposedException'
  • 'FormatException'
  • 'TimeoutException'
  • 'OperationCanceledException'

These are good candidates because their meanings are well understood across the .NET ecosystem.

csharp
1using System;
2
3public static class MathHelpers
4{
5    public static int DividePositive(int numerator, int denominator)
6    {
7        if (denominator == 0)
8            throw new ArgumentOutOfRangeException(nameof(denominator), "Denominator must not be zero.");
9
10        if (numerator < 0)
11            throw new ArgumentOutOfRangeException(nameof(numerator), "Numerator must be non-negative.");
12
13        return numerator / denominator;
14    }
15}

Match the Exception to the Failure

The real question is not "what am I allowed to throw". It is "what failed, exactly?"

Use ArgumentNullException when the caller omitted a required argument.

csharp
1public static string Normalize(string input)
2{
3    if (input is null)
4        throw new ArgumentNullException(nameof(input));
5
6    return input.Trim();
7}

Use InvalidOperationException when the method exists and the arguments are valid, but the object's current state makes the operation illegal.

csharp
1public class Connection
2{
3    public bool IsOpen { get; private set; }
4
5    public void Send(string message)
6    {
7        if (!IsOpen)
8            throw new InvalidOperationException("Connection is not open.");
9
10        Console.WriteLine(message);
11    }
12}

That distinction makes error handling much easier for callers.

Exceptions You Usually Should Not Throw Manually

Some built-in exceptions are technically throwable but are usually the wrong semantic choice in application code.

Examples include:

  • 'NullReferenceException'
  • 'IndexOutOfRangeException'
  • 'AccessViolationException'
  • 'StackOverflowException'
  • 'OutOfMemoryException'

Those exceptions typically represent runtime failures, corrupted process state, or CLR-level problems rather than cleanly designed application contracts.

For example, if an index parameter is invalid, throw ArgumentOutOfRangeException rather than manually throwing IndexOutOfRangeException.

When a Custom Exception Makes Sense

Custom exceptions are useful when the failure is domain-specific and built-in exception names are too generic. A payment workflow, scheduling engine, or business-rules subsystem may have errors that deserve first-class names.

Even then, do not overuse custom exceptions for routine validation. Most bad arguments and bad object states are already well covered by standard framework types.

A Simple Selection Rule

A practical rule set looks like this:

  1. If the caller passed a bad argument, use an Argument* exception.
  2. If the object is in the wrong state, use InvalidOperationException.
  3. If the operation is intentionally unsupported, use NotSupportedException.
  4. If the failure belongs to your business domain, consider a custom exception.

That covers most application code cleanly.

Common Pitfalls

A common mistake is manually throwing runtime-failure exceptions such as NullReferenceException or IndexOutOfRangeException because they sound familiar.

Another mistake is creating custom exceptions for simple argument validation, which makes APIs noisier without adding precision.

It is also easy to forget useful context. Argument-related exceptions should usually include the parameter name, and messages should explain what rule was violated.

Summary

  • Throw built-in .NET exceptions when they accurately describe the problem.
  • 'Argument* exceptions and InvalidOperationException are common, appropriate choices.'
  • Avoid manually throwing exceptions that usually indicate runtime or CLR failures.
  • Use custom exceptions only when the failure is genuinely domain-specific.
  • Pick the exception type based on the contract that failed, not on naming convenience.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the 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.