;

Custom Exception Type in C#


Custom exceptions in C# allow developers to create error types that more accurately describe problems unique to their applications. This tutorial will explore custom exceptions, discuss when to use them, and provide real-world examples to deepen your understanding.

Introduction to Custom Exceptions

In C#, exceptions allow a program to handle unexpected issues, preventing crashes and allowing for meaningful user messages. However, predefined exceptions may not always be descriptive enough for application-specific issues. Custom exceptions fill this gap, providing precise error information tailored to your application’s logic.

Creating a Custom Exception

To create a custom exception, we inherit from the base Exception class or another specific exception. Custom exceptions often include unique properties or methods to provide more detailed error handling capabilities.

Basic Structure of a Custom Exception

using System;

public class CustomException : Exception
{
    public CustomException() { }
    public CustomException(string message) : base(message) { }
    public CustomException(string message, Exception inner) : base(message, inner) { }
}

Example: InvalidAgeException

Let’s create a custom exception that triggers if a user provides an age that’s not within a valid range.

using System;

public class InvalidAgeException : Exception
{
    public int ProvidedAge { get; }
    
    public InvalidAgeException(int age) 
        : base("Age must be between 0 and 120.")
    {
        ProvidedAge = age;
    }
    
    public override string ToString()
    {
        return $"InvalidAgeException: Provided age {ProvidedAge} is out of acceptable range.";
    }
}

Here, InvalidAgeException inherits from Exception and adds an ProvidedAge property to store the invalid age, making it easier to track specific issues.

When to Use Custom Exceptions

Custom exceptions are most useful when:

  1. Standard Exceptions Lack Clarity: If a standard exception like ArgumentException doesn’t fully capture the problem, a custom exception can provide better detail.
  2. Multiple Exception Types Needed: In complex applications, custom exceptions help categorize issues and distinguish between different error types.
  3. Enforcing Business Rules: Custom exceptions can enforce specific business rules, such as validating application-specific conditions.

For example, if a banking application requires all deposits to be above $10, a custom exception named MinimumDepositException could enforce this rule effectively.

Real-World Example: Bank Account System

In a banking application, we often need strict validation rules for transactions. Let’s create custom exceptions for these scenarios:

  1. InsufficientFundsException: Triggered when a withdrawal exceeds the account balance.
  2. MinimumDepositException: Ensures deposits meet a minimum threshold.

Example

using System;

// Custom Exception for Insufficient Funds
public class InsufficientFundsException : Exception
{
    public double AccountBalance { get; }
    
    public InsufficientFundsException(double balance)
        : base("Insufficient funds for the requested withdrawal.")
    {
        AccountBalance = balance;
    }

    public override string ToString()
    {
        return $"InsufficientFundsException: Available balance is {AccountBalance}.";
    }
}

// Custom Exception for Minimum Deposit Violation
public class MinimumDepositException : Exception
{
    public double MinimumDeposit { get; }
    
    public MinimumDepositException(double minDeposit)
        : base($"Deposit must be at least {minDeposit}.")
    {
        MinimumDeposit = minDeposit;
    }

    public override string ToString()
    {
        return $"MinimumDepositException: Deposit must meet minimum of {MinimumDeposit}.";
    }
}

// Bank Account Class Demonstrating Custom Exceptions
public class BankAccount
{
    public double Balance { get; private set; }

    public BankAccount(double initialBalance)
    {
        Balance = initialBalance;
    }

    public void Withdraw(double amount)
    {
        if (amount > Balance)
        {
            throw new InsufficientFundsException(Balance);
        }
        Balance -= amount;
        Console.WriteLine($"Withdrawal of {amount} successful. New balance: {Balance}");
    }

    public void Deposit(double amount)
    {
        const double MinDeposit = 10.0;
        if (amount < MinDeposit)
        {
            throw new MinimumDepositException(MinDeposit);
        }
        Balance += amount;
        Console.WriteLine($"Deposit of {amount} successful. New balance: {Balance}");
    }
}

// Demonstrating Custom Exceptions in Action
class Program
{
    static void Main()
    {
        var account = new BankAccount(100);

        try
        {
            account.Withdraw(150);
        }
        catch (InsufficientFundsException ex)
        {
            Console.WriteLine(ex);
        }

        try
        {
            account.Deposit(5);
        }
        catch (MinimumDepositException ex)
        {
            Console.WriteLine(ex);
        }
    }
}

Explanation

  • Insufficient Funds Check: If a withdrawal request exceeds the account balance, InsufficientFundsException is thrown. This gives specific feedback on the insufficient balance.
  • Minimum Deposit Check: The MinimumDepositException is triggered when a deposit doesn’t meet the minimum amount. This ensures the application meets business rules.

In this example, each exception gives a targeted message, helping both users and developers understand the exact issue.

Key Takeaways

  • Clarity with Custom Exceptions: Custom exceptions provide specific messages and data, helping to clarify application-specific errors.
  • Effective Use Cases: Use custom exceptions for business rules, validations, and scenarios where standard exceptions lack detail.
  • Enhanced Debugging: Custom exceptions improve debugging by offering specific information about the error context, like invalid parameters or violated constraints.
  • Extensibility: Well-designed custom exceptions make applications more extensible and easier to maintain.

Summary

Custom exceptions in C# offer a way to create error handling suited to specific application needs. By deriving from the base Exception class and adding meaningful properties, custom exceptions provide clarity and maintainability to your codebase. In our banking example, using InsufficientFundsException and MinimumDepositException demonstrated how custom exceptions enforce business rules effectively, ensuring that users receive clear and relevant feedback during error conditions.