Curriculum
Custom Exceptions, Throw, Throws, and Exception Propagation in C# are advanced exception handling concepts that help developers create meaningful error messages, enforce business rules, and build professional enterprise applications. While built-in exceptions handle common runtime errors, Custom Exceptions, Throw, Throws, and Exception Propagation in C# allow developers to create application-specific error handling mechanisms that improve maintainability, debugging, and user experience.
Understanding Custom Exceptions, Throw, Throws, and Exception Propagation in C# is essential for developing scalable ASP.NET Core Applications, Web APIs, Banking Applications, E-Commerce Platforms, Hospital Management Systems, and Enterprise Software Solutions.
Built-in exceptions such as:
DivideByZeroException
NullReferenceException
FormatException
FileNotFoundException
handle general programming errors.
However, real-world business applications often require custom error handling.
Examples:
Insufficient Account Balance
Invalid Student Enrollment
Duplicate Employee Record
Age Restriction Violation
Invalid Product Stock
These scenarios require custom exceptions.
A Custom Exception is a user-defined exception class created by inheriting from the Exception class.
Custom Exceptions help developers:
All exceptions ultimately derive from:
System.Exception
Hierarchy:
Object
|
Exception
|
CustomException
When creating a custom exception, the new class typically inherits from:
Exception
Example:
public class InvalidAgeException :
Exception
{
public InvalidAgeException(
string message)
: base(message)
{
}
}
This custom exception can now be used throughout the application.
Example:
public class Student
{
public void Register(int age)
{
if(age < 18)
{
throw new
InvalidAgeException(
"Student must be at least 18 years old.");
}
Console.WriteLine(
"Registration Successful");
}
}
Usage:
try
{
Student student =
new Student();
student.Register(15);
}
catch(InvalidAgeException ex)
{
Console.WriteLine(
ex.Message);
}
Output:
Student must be at least 18 years old.
This provides a meaningful business-specific error.
The throw keyword is used to manually generate an exception.
Syntax:
throw new Exception(
"Error Message");
The throw keyword immediately stops execution and transfers control to the nearest catch block.
Example:
int age = 15;
if(age < 18)
{
throw new Exception(
"Age must be 18 or above.");
}
Output:
Exception Thrown
The exception is generated intentionally.
Example:
string name = "";
if(string.IsNullOrEmpty(name))
{
throw new
ArgumentException(
"Name cannot be empty.");
}
Output:
Name cannot be empty.
This approach is commonly used for validation.
Example:
public class BankAccount
{
public double Balance =
5000;
public void Withdraw(
double amount)
{
if(amount > Balance)
{
throw new Exception(
"Insufficient Balance");
}
Balance -= amount;
}
}
Usage:
BankAccount account =
new BankAccount();
account.Withdraw(10000);
Output:
Insufficient Balance
Business rules can be enforced using exceptions.
Exception Propagation refers to the process of transferring an exception from one method to another until a matching handler is found.
Example:
MethodA()
|
MethodB()
|
MethodC()
If MethodC throws an exception:
MethodC → MethodB → MethodA
The exception travels upward through the call stack.
This process is called Exception Propagation.
Method C:
public void MethodC()
{
throw new Exception(
"Error in Method C");
}
Method B:
public void MethodB()
{
MethodC();
}
Method A:
public void MethodA()
{
MethodB();
}
Usage:
try
{
MethodA();
}
catch(Exception ex)
{
Console.WriteLine(
ex.Message);
}
Output:
Error in Method C
The exception propagated upward until it was handled.
Consider:
Main()
|
ProcessOrder()
|
ValidatePayment()
|
CheckBalance()
If CheckBalance() throws an exception:
CheckBalance
→ ValidatePayment
→ ProcessOrder
→ Main
The exception moves upward through the call stack.
Understanding this flow is important for debugging.
Sometimes developers need to perform additional processing before passing the exception upward.
Example:
try
{
int result =
10 / 0;
}
catch(Exception)
{
Console.WriteLine(
"Logging Error");
throw;
}
The exception continues propagating after logging.
Correct:
throw;
Incorrect:
throw ex;
Why?
throw preserves stack trace
throw ex resets stack trace
Best practice is to use:
throw;
when re-throwing exceptions.
Example:
public class InsufficientBalanceException :
Exception
{
public InsufficientBalanceException()
: base(
"Insufficient account balance.")
{
}
public InsufficientBalanceException(
string message)
: base(message)
{
}
}
Usage:
throw new
InsufficientBalanceException();
This is the standard enterprise approach.
Examples:
InvalidStudentException
InvalidOrderException
DuplicateUserException
PaymentFailedException
ProductOutOfStockException
Large applications often contain dozens of custom exceptions.
Example:
if(product.Stock == 0)
{
throw new
ProductOutOfStockException(
"Product is unavailable.");
}
Controller:
catch(ProductOutOfStockException ex)
{
return BadRequest(
ex.Message);
}
This improves API responses and maintainability.
Example:
if(orderAmount < 500)
{
throw new Exception(
"Minimum order amount is 500.");
}
Exceptions can enforce business requirements.
Application-specific errors become easier to understand.
Developers quickly identify issues.
Business rules become easier to manage.
Applications become more professional.
The same exception can be reused throughout the application.
Avoid:
throw new Exception(
"Error");
Prefer meaningful custom exceptions.
Always provide descriptive messages.
Exceptions should handle unexpected situations only.
Create custom exceptions only when necessary.
Avoid resetting the stack trace.
InsufficientBalanceException
InvalidTransactionException
AccountLockedException
OutOfStockException
InvalidCouponException
PaymentFailedException
InvalidPatientException
DoctorUnavailableException
AppointmentConflictException
StudentNotFoundException
CourseFullException
InvalidEnrollmentException
These exceptions help enforce business logic.
A Custom Exception is a user-defined exception class derived from Exception.
The throw keyword is used to manually generate exceptions.
Exception Propagation is the process of passing exceptions up the call stack until they are handled.
throw preserves the original stack trace while throw ex resets it.
Custom Exceptions provide meaningful business-specific error handling.
A Custom Exception is a user-defined exception class used to represent application-specific errors.
The throw keyword is used to generate exceptions manually.
Exception Propagation is the movement of exceptions through the call stack until they are handled.
throw preserves stack trace information while throw ex resets it.
Custom Exceptions should be used for business rules and application-specific error scenarios.
They improve code organization, debugging, maintainability, and error handling consistency.
WhatsApp us