.NET
custom exceptions
Exception
ApplicationException
error handling

Should I derive custom exceptions from Exception or ApplicationException in .NET?

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

In modern .NET code, custom exceptions should normally derive directly from Exception, not ApplicationException. ApplicationException was originally intended as a marker for user-defined exceptions, but it never established useful framework behavior, and current guidance treats it as unnecessary extra hierarchy.

Derive from Exception

If you need a custom exception type, inherit from Exception and give the type a name that describes the failure clearly.

csharp
1using System;
2
3public sealed class InvalidOrderStateException : Exception
4{
5    public InvalidOrderStateException()
6    {
7    }
8
9    public InvalidOrderStateException(string message) : base(message)
10    {
11    }
12
13    public InvalidOrderStateException(string message, Exception innerException)
14        : base(message, innerException)
15    {
16    }
17}

This is the standard pattern because callers already catch by specific type or by Exception when they genuinely mean all application failures.

Why ApplicationException is not helpful

ApplicationException does not add semantics that the runtime or base class libraries use meaningfully. Catch blocks rarely distinguish between ApplicationException and other exception subtypes, and framework code does not treat it as a special category.

In other words, deriving from ApplicationException adds one more base class without improving diagnosability, recovery, or API design.

Use custom exceptions only when the caller can act on them

Not every error deserves a custom exception. Create one when the type communicates something actionable or domain-specific.

Good reasons include:

  • The caller may catch that exact condition and recover.
  • The error represents a business rule, not a generic programming fault.
  • The exception type makes logs and public API behavior clearer.

If the failure is just a bad argument, ArgumentException, ArgumentNullException, or InvalidOperationException may already be enough.

csharp
1public void SetQuantity(int quantity)
2{
3    if (quantity < 0)
4    {
5        throw new ArgumentOutOfRangeException(nameof(quantity));
6    }
7}

Do not invent NegativeQuantityException unless the extra type really buys something.

Keep the exception simple and descriptive

A custom exception should usually expose a clear message and optionally structured context when the caller needs it.

csharp
1using System;
2
3public sealed class SubscriptionExpiredException : Exception
4{
5    public DateTime ExpiredAt { get; }
6
7    public SubscriptionExpiredException(DateTime expiredAt)
8        : base($"Subscription expired at {expiredAt:O}.")
9    {
10        ExpiredAt = expiredAt;
11    }
12}

If you add properties, make sure they are stable and useful. Avoid turning exceptions into bulky data-transfer objects.

Catch specific exceptions, not ancestry markers

One argument historically made for ApplicationException was that it would help separate application failures from system failures. In practice, code should catch the specific exceptions it can handle. Catching a broad ancestry marker is usually a sign that the handler does not really understand the error cases.

That is why deriving from Exception works fine: callers either catch your specific custom type, or they do not.

Common Pitfalls

  • Deriving from ApplicationException because it sounds more specialized even though it adds no practical value.
  • Creating custom exceptions for cases that existing framework exceptions already describe well.
  • Throwing very broad exceptions and expecting callers to infer the real problem from the message text.
  • Adding too many custom properties that no caller actually uses.
  • Catching Exception everywhere instead of handling only specific failures that can be recovered from.

Summary

  • In modern .NET, custom exceptions should usually inherit directly from Exception.
  • 'ApplicationException is legacy structure, not useful behavior.'
  • Create a custom exception only when the type communicates something actionable.
  • Prefer built-in exception types for common argument and state errors.
  • Keep custom exception classes small, clear, and focused on recoverable meaning.

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.