0% found this document useful (0 votes)
16 views49 pages

c# assignment.pdf

The document is a project report on Exception Handling in C# by students from BahirDar Institute of Technology. It covers various aspects of exception handling, including mechanisms, types, and best practices, emphasizing the importance of structured error management in software development. The report also includes a detailed table of contents and outlines the differences between errors and exceptions, along with examples of handling exceptions in code.

Uploaded by

kalkalkidan497
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views49 pages

c# assignment.pdf

The document is a project report on Exception Handling in C# by students from BahirDar Institute of Technology. It covers various aspects of exception handling, including mechanisms, types, and best practices, emphasizing the importance of structured error management in software development. The report also includes a detailed table of contents and outlines the differences between errors and exceptions, along with examples of handling exceptions in code.

Uploaded by

kalkalkidan497
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 49

BahirDar Institute of Technology

Faculty of Computing (Information Technology)

Advanced Database(G6 project)


Students Name ld
1.KALKIDAN TILAHUN ............ 1506668
2.TESFALEM TEKLEMARIAM ..... 1507932
3. NATNAEL TEMESGEN ............ 1512556
4.MEWUDED TESFAHUNEGN........1507141
5.TSION TESFAYE ........................1508052
6.YONAS TESHOME.................. 1508367
7. HAYMANOT WORKU............... 1506489
8.DESKIOUS YISMAW................ 1505724
9.YORDANOS YITBAREK............. 1508409
10.BELAY ZELEK......................... 1505278

submission date:

submitted to:

1
Table of Contents
page
Exception handling in c#.net...........................................................................3

2
introduction..................................................................................................3
1. Introduction to Exception Handling in C#....................................................5
1.1 What is an Exception?........................................................................5
1.2 Importance of Exception Handling......................................................5
1.3 Errors vs. Exceptions in C#................................................................6
2.Exception Handling Mechanisms in C#.....................................................7
2.1 The try, catch, and finally Blocks.........................................................8
2.2 Re-throwing Exceptions:
…………………………………………………………………12

2.3 Re-throwing Exceptions (throw; vs. throw ex;)..................................12


3.Exception Types in C#.............................................................................13
Built-in Exceptions (System.Exception and Derived Classes)..................13
Common Runtime Exceptions (DivideByZeroException,
NullReferenceException, etc.).................................................................15
3. NullReferenceException (Accessing Null Object).................................16
User-defined (Custom) Exceptions..........................................................20
4. Exception Hierarchy in C#...................................................................21
Checked vs. Unchecked Exceptions.........................................................27
4.3 Exception Inheritance Structure.......................................................29
5. Handling Multiple Exceptions..................................................................29
Using Multiple catch Blocks in C#...........................................................29
Filtering Exceptions Using catch when in C#...........................................32
. Basic Nested Try-Catch Block................................................................33
6. Creating and Using Custom Exceptions..................................................36
Definition of a Custom Exception Class in C#.........................................36
Implementation of Custom Exception Handling in C#.............................36
Adding Custom Properties and Methods to a Custom Exception in C#. . .37
7. Exception Propagation and Best Practices..............................................39
Exception Propagation Across Methods...................................................39
Best Practices in Exception Handling......................................................40
Writing Meaningful Error Messages.........................................................40

3
Avoiding Overuse of Try-Catch Blocks.....................................................41
8. Exception Handling in Delegates and Events.........................................41
Managing Exceptions in Event-Driven Programming...............................41
Exception Handling in Callback Functions...............................................42
9. Global Exception Handling in C#............................................................43
Using AppDomain.UnhandledException in C#.........................................43
Implementing Global Exception Handling in Web Applications (ASP.NET)
................................................................................................................44
10. Debugging and Error Recovery Strategies............................................45
Using Debuggers (Visual Studio Exception Settings)...............................45
Graceful Degradation and Recovery........................................................45
11 Summery..............................................................................................46
12 References.............................................................................................47

4
Exception handling in c#.net

introduction
Exception handling in C# is a structured approach to managing runtime
errors and ensuring that applications continue functioning smoothly under
unexpected conditions. By using try, catch, finally, and throw blocks,
developers can anticipate potential failures, respond appropriately, and
prevent abrupt crashes.

Exceptions in C# arise due to various issues, such as invalid input, resource


unavailability, or logical mistakes. Instead of terminating a program
immediately, exception handling allows developers to define specific
responses for different error scenarios, making applications more reliable and
user-friendly.

5
By leveraging built-in exception types, creating custom exceptions, and
following best practices such as meaningful error logging and avoiding
generic exception catching, developers can build robust software that adapts
to varying runtime challenges. Effective exception handling not only
enhances maintainability but also contributes to an improved user
experience by providing informative error messages and graceful recovery
mechanisms.

6
1. Introduction to Exception Handling in C#
 What is an Exception?

 Importance of Exception Handling

 Errors vs. Exceptions in C#

1.1 What is an Exception?


 📌 An exception is an error that occurs during program execution,
disrupting normal flow.

 📌 Exceptions arise due to unexpected conditions (e.g., invalid input,


division by zero, null references).

 📌 C# provides a structured exception-handling mechanism using


try, catch, finally, and throw.

 📌 Handling exceptions ensures that the program can continue


running despite errors.

Example:

csharp

int number = int.Parse("abc"); // Causes FormatException

Exceptions must be handled properly to prevent crashes.

1.2 Importance of Exception Handling


 ✅ Prevents program crashes by gracefully managing errors.

 ✅ Improves code reliability and maintainability.

 ✅ Enhances the user experience by preventing unexpected failures.

 ✅ Helps developers debug errors efficiently by logging detailed


exception data.

7
 ✅ Ensures critical resources (e.g., files, database connections) are
properly released.

Example using try-catch

try

int number = int.Parse("abc"); // FormatException occurs

catch (FormatException ex)

Console.WriteLine("Handled Exception: Invalid format.");

Exception handling prevents runtime failures and ensures stable


execution.

1.3 Errors vs. Exceptions in C#


Errors

Errors are unexpected issues that occur at a system level and often
indicate serious problems, such as:

 Syntax errors: Issues in the code that prevent compilation


(e.g., missing

semicolons, typos).

 Logical errors: Bugs in the program that lead to incorrect


results.
 Runtime errors: Problems like insufficient memory or
hardware failures.

Errors generally cannot be handled by the program itself. They often


require debugging and fixes in the code before execution.

Exceptions

8
Exceptions are runtime issues that disrupt the normal flow of a
program but can be handled gracefully using a try-catch block.
Common exceptions include:

 DivideByZeroException: Occurs when dividing by zero.


 NullReferenceException: Happens when accessing an
object reference that is null.
 IndexOutOfRangeException: Triggered when accessing an
invalid array index.

C# provides a structured way to handle exceptions using try, catch, and


finally:
try
{
int result = 10 / 0; // This will cause DivideByZeroException
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Cannot divide by zero!");
}
finally
{
Console.WriteLine("Execution completed.");
}
Exceptions are part of the System.Exception class and can be caught,
logged, or even rethrown for further handling.

Key Differences

Aspect Errors Exceptions

Occurrenc Compile-time or
Only at runtime
e runtime

Recoverabl Yes, if handled


Usually no
e? properly

Managed with try-


Handling Requires fixing code
catch

2.Exception Handling Mechanisms in C#


 The try, catch, and finally Blocks

9
 Throwing Exceptions (throw Keyword)

 Re-throwing Exceptions (throw vs. throw ex)

Exception handling in C# is a mechanism that allows a program to detect,


handle, and recover from runtime errors gracefully, instead of crashing
unexpectedly.

2.1 The try, catch, and finally Blocks


Key Components of Exception Handling

1. Try Block: This contains the code that may cause an exception.

2. Catch Block: This handles exceptions when they occur.

3. Finally Block: This executes code regardless of whether an exception


occurs.

4. Throw Statement: This generates an exception manually.

2.1.1 The try Block

The try block contains the code that might throw an exception. It ensures that risky
operations (such as division by zero or accessing null references) are caught.
Example:
try
{
int num = 10;
int result = num / 0; // Exception occurs here
Console.WriteLine(result);
}
If an exception occurs inside the try block, control immediately passes to the catch
block.

2.1.2 The catch Block


The catch block handles the exception and prevents the program from crashing. You can
define multiple catch blocks to handle different exception types separately.
Example:
try
{
int[] numbers = {1, 2, 3};
Console.WriteLine(numbers[5]); // IndexOutOfRangeException

10
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine($"Exception caught: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine("An unexpected error occurred.");
}
📌 Best Practice: Catch specific exceptions first before using a generic catch (Exception
ex) block.
2.1.3 The finally Block
The finally block always executes whether an exception occurs or not. It's commonly
used for cleanup operations like closing files or database connections.
The throwstatement
– Allows a user/programmer to throw an exception object
• E.g.:
throw new Exception("Exception in Throw-Test Method" );
– string passed to exception object’s constructor becomes exception object’s error
message
– Can throw only an object of class Exception or one of its derived classes
– You can customize the exception type thrown from methods
// Using finally blocks.
using System;
// demonstrating that ‘finally’ always executes
class UsingExceptions
{
entry point for application
static void Main( string[] args )
{
// Case 1: No exceptions occur in called method.

11
Console.WriteLine( "Calling DoesNotThrowException" );
DoesNotThrowException();
// Case 2: Exception occurs in called method and is caught
// in called method.
Console.WriteLine( "\nCalling ThrowExceptionWithCatch" );
Console.WriteLine( "\nCalling ThrowExceptionWithCatch" );
ThrowExceptionWithCatch();
// Case 3: Exception occurs in called method, but not caught
// in called method, because no catch handlers in called method.
Console.WriteLine( 24 "\nCalling ThrowExceptionWithoutCatch" );
// call ThrowExceptionWithoutCatch
try
{
ThrowExceptionWithoutCatch();
}
// process exception returned from
// ThrowExceptionWithoutCatch
catch
{
Console.WriteLine( "Caught exception from " + 37 "ThrowExceptionWithoutCatch in
Main" );
}
// Case 4: Exception occurs in called method and is caught
// in called method, then rethrown to caller.
Console.WriteLine( 43 "\nCalling ThrowExceptionCatchRethrow" );
// call ThrowExceptionCatchRethrow
try

12
{
ThrowExceptionCatchRethrow();
}
}
// process exception returned from
// ThrowExceptionCatchRethrow
catch
{
Console.WriteLine( "Caught exception from " + "ThrowExceptionCatchRethrow in
Main" );
}
} // end method Main

2.1.4 Throw block

In C#, the throw keyword is used to raise exceptions within a program. A


throw block typically appears inside a try-catch statement or a method,
allowing developers to explicitly signal that an error has occurred.
Key Points:
 Usage: The throw statement is used to create exceptions and
terminate the current flow of execution.
 Syntax: It is often used inside a try block or when handling exceptions
in a catch block.
Example:
try
{
int result = 10 / 0; // This will cause a divide-by-zero
exception
}
catch (Exception ex)
{
13
throw new InvalidOperationException("An error occurred",
ex);
}
2.2 Re-throwing Exceptions: If used inside a catch block without
arguments (throw;), it preserves the original stack trace.

2.3 Re-throwing Exceptions (throw; vs. throw ex;)


1. throw; preserves the original stack trace
o When an exception is caught and re-thrown using throw;, the
stack trace remains unchanged.
o This is useful for debugging because the original error location is
visible.
2. throw ex; resets the stack trace
o Using throw ex; within a catch block makes it appear as if the
exception originated at the throw ex; statement.
o This can obscure the actual source of the error, making
debugging more difficult.
3. Best Practice: Always use throw; unless modifying the
exception
o If the goal is to log the error and re-throw it, throw; is the
recommended approach.
o If you need to modify the exception (e.g., changing the error
message), use throw new Exception("New message", ex);.
4. Example demonstrating the difference

try
{
int result = 10 / 0; // Causes a divide-by-zero exception
}
catch (Exception ex)
{
Console.WriteLine("Error caught!");

// Wrong approach: resets the stack trace


throw ex;

// Correct approach: maintains original error details


throw;
}
5. Impact on debugging

14
o throw; helps developers track down the exact location of the
exception.
o throw ex; can lead to misleading stack traces, making
troubleshooting harder.

3.Exception Types in C#
 Built-in Exceptions (System.Exception and Derived Classes)

 Common Runtime Exceptions (DivideByZeroException,


NullReferenceException, etc.)

 User-defined (Custom) Exceptions

3.1 Built-in Exceptions (System.Exception and Derived Classes)


3.1.1. Overview of Built-in Exceptions in C#
 C# provides a robust exception handling system through built-in
exception classes.

 All exceptions are derived from the System.Exception base class.

 These built-in exceptions handle various runtime errors such as


division by zero, invalid operations, file access errors, and type
mismatches.

3.1.2. System.Exception (Base Class)


 System.Exception is the base class for all exceptions in C#.

 It provides fundamental properties like:

o Message → Describes the error.

o StackTrace → Shows where the error occurred.

o InnerException → Stores nested exceptions if one caused


another.

✅ Example: Throwing a Base Exception

throw new Exception("An error occurred in the application.");

 This is the generic exception type, but specific exceptions are


preferred for better error handling.

3.1.3. Common Derived Exception Classes

15
a) System.SystemException

 The base class for system-level exceptions (e.g., arithmetic errors,


null references).

b) System.ApplicationException

 Used for application-defined exceptions (but rarely used today).

c) System.NullReferenceException

 Occurs when trying to access a member of an object that is null.

 Example: Calling a method on an uninitialized object reference.

🚫 Example: Causes a Null Reference Exception

csharp

string text = null;

Console.WriteLine(text.Length); // Error: NullReferenceException

3.1.4. Specific Built-in Exceptions


a) Arithmetic Exceptions

 System.DivideByZeroException → Raised when dividing by zero.

 System.OverflowException → Occurs when a numeric operation


exceeds limits.

b) Type-Related Exceptions

 System.InvalidCastException → Thrown when a failed type


conversion occurs.

 System.FormatException → Raised for invalid data formats (e.g.,


incorrect parsing).

c) File & IO Exceptions

 System.IO.FileNotFoundException → Raised when a file is missing.

 System.IO.IOException → Generic exception for file-handling errors.

d) Argument Exceptions

 System.ArgumentException → Thrown for invalid arguments passed


to a method.

16
 System.ArgumentNullException → Raised when a null argument is
unexpectedly used.

3.1.5. Exception Handling Best Practices


 ✅ Always use specific exceptions instead of the generic Exception
class.

 🔍 Log exceptions using ex.Message and ex.StackTrace for debugging.

 🚀 Use try-catch-finally to ensure graceful error handling.

✅ Example: Handling a Specific Exception

try
{
int result = 10 / 0;
}
catch (DivideByZeroException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
 This ensures that only DivideByZeroException is handled properly.

3.1.6. : Common Built-in Exceptions


Exception Class Description Example

NullReferenceExcept Occurs when accessing string text = null;


ion null text.Length;

DivideByZeroExcepti Raised when dividing by


int result = 10 / 0;
on zero

InvalidCastException Failed type conversion (int)obj;

FileNotFoundExcepti
Missing file error File.ReadAllText("missing.txt
on
");

3.2 Common Runtime Exceptions (DivideByZeroException,


NullReferenceException, etc.)
17
3.2.1. Overview of Common Runtime Exceptions
 Runtime exceptions occur while the program is running due to
logical errors, invalid operations, or unexpected conditions.
 These exceptions are automatically thrown by the CLR (Common
Language Runtime) when a program encounters issues.
 Proper exception handling using try-catch blocks can prevent
application crashes and improve stability.
3.2.2. DivideByZeroException (Arithmetic Error)
 Occurs when a program attempts to divide a number by zero.
 This is an arithmetic exception automatically raised by the CLR.
🚫 Example: Causes DivideByZeroException
csharp
int result = 10 / 0; // ERROR: Division by zero is not allowed
 The above code will fail because division by zero is undefined.
✅ Handling the Exception
csharp
try
{
int result = 10 / 0; // Causes exception
}
catch (DivideByZeroException ex)
{
Console.WriteLine($"Error: {ex.Message}"); // Displays error
message
}
 A try-catch block ensures that the program does not crash
unexpectedly.

3.2.1. NullReferenceException (Accessing Null Object)


 Occurs when attempting to access a member of an object that
is null.
 This happens when a variable is declared but not initialized before
use.
🚫 Example: Causes NullReferenceException
csharp
string text = null;
Console.WriteLine(text.Length); // ERROR: Object reference not set to
an instance
 Since text is null, trying to access Length causes the exception.
✅ Handling the Exception

18
csharp
string text = null;

try
{
Console.WriteLine(text.Length); // Causes exception
}
catch (NullReferenceException ex)
{
Console.WriteLine("Error: The object is null.");
}
 Always check if an object is null before accessing its properties.

3.2.2. IndexOutOfRangeException (Invalid Array Index)


 Occurs when trying to access an array index that does not
exist.
 Arrays in C# are zero-based, meaning the first index is 0.
🚫 Example: Causes IndexOutOfRangeException
csharp
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[5]); // ERROR: Index 5 is out of bounds
 There is no index 5, leading to an exception.
✅ Handling the Exception
csharp
int[] numbers = { 1, 2, 3 };

try
{
Console.WriteLine(numbers[5]); // Causes exception
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("Error: Invalid array index.");
}
 Always validate indices before accessing an array element.

3.2.3. InvalidCastException (Type Conversion Error)


 Occurs when attempting an illegal type conversion.
 The conversion fails if the types are incompatible.
🚫 Example: Causes InvalidCastException
csharp

19
object obj = "Hello";
int num = (int)obj; // ERROR: Cannot convert a string to an integer
 Since "Hello" is a string, it cannot be cast to an int.
✅ Handling the Exception
csharp
object obj = "Hello";

try
{
int num = (int)obj; // Causes exception
}
catch (InvalidCastException ex)
{
Console.WriteLine("Error: Type conversion is invalid.");
}
 Use safe conversion methods like Convert.ToInt32() or int.TryParse().

3.2.4. FormatException (Invalid Data Format)


 Occurs when parsing data that does not match the expected
format.
 Common in string-to-number conversions.
🚫 Example: Causes FormatException
csharp
string input = "abc";
int number = int.Parse(input); // ERROR: "abc" is not a valid integer
 "abc" cannot be converted to an integer, leading to an exception.
✅ Handling the Exception
csharp
string input = "abc";

try
{
int number = int.Parse(input); // Causes exception
}
catch (FormatException ex)
{
Console.WriteLine("Error: Invalid format.");
}
 Always validate user input before parsing data.

20
3.2.5. FileNotFoundException (Missing File Error)
 Occurs when trying to access a file that does not exist.
 Raised when using file handling methods like File.ReadAllText().
🚫 Example: Causes FileNotFoundException
csharp
string content = File.ReadAllText("nonexistent.txt"); // ERROR: File not
found
 If "nonexistent.txt" does not exist, the exception occurs.
✅ Handling the Exception
csharp
try
{
string content = File.ReadAllText("nonexistent.txt"); // Causes
exception
}
catch (FileNotFoundException ex)
{
Console.WriteLine("Error: The file does not exist.");
}
 Always check if the file exists before attempting to read it.

3.2.6. Summary Table: Common Runtime Exceptions


Exception Class Cause Example

Division
DivideByZeroException int result = 10 / 0;
by zero

Accessin
NullReferenceExceptio string text = null;
g a null
n text.Length;
object

Using an
IndexOutOfRangeExce invalid array[5] on a 3-element
ption array array
index

Illegal
type (int)obj; when obj is a
InvalidCastException
conversi string
on

FormatException Parsing int.Parse("abc");

21
Exception Class Cause Example

invalid
data
format

Trying to
read a
non-
File.ReadAllText("missing.
FileNotFoundException existent
txt");
file

3.2.7. Best Practices for Handling Runtime Exceptions


 ✅ Always use specific exceptions (e.g., DivideByZeroException)
instead of a generic Exception.
 🔍 Log error details using ex.Message for debugging purposes.
 🔹 Perform input validation before calling conversion methods like
Parse().
 🚀 Use try-catch-finally blocks to ensure graceful error handling.
 🏆 Use custom exceptions for application-specific errors when
necessary

3.3 User-defined (Custom) Exceptions


User-Defined Exception Basics
 🔹 Custom exceptions help identify specific error scenarios in
an application.
 🔹 They make debugging easier by providing meaningful error
messages.
 🔹 They improve code organization by categorizing errors.
3.3.1 Creating a Custom Exception
 🟢 Inherit from Exception (or a subclass like
ApplicationException).
 🟢 Define constructors to initialize the exception message.

22
 🟢 Optionally, add properties or methods for additional
functionality.

public class CustomException : Exception


{
public CustomException(string message) : base(message)
{}
}
3.3.2 Throwing a Custom Exception

 ✅ Use the throw keyword inside your code.


 ✅ Provide a descriptive message to clarify the error.
csharp
throw new CustomException("Custom error occurred!");
Handling a Custom Exception
 📌 Use try-catch blocks for safe exception handling.
 📌 Catch the exception and perform appropriate actions.

try
{
throw new CustomException("Something went wrong.");
}
catch (CustomException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
3.3.3 Best Practices for Custom Exceptions

 ⚡ Be specific—name exceptions clearly (e.g.,


InvalidInputException).
 ⚡ Keep it lightweight—avoid unnecessary code.
 ⚡ Use logging—record exceptions for debugging.

4. Exception Hierarchy in C#

23
 Base Class (System.Exception)

 Checked vs. Unchecked Exceptions

 Exception Inheritance Structure

4.1 Base Class (System.Exception)

Basic Class Exception (System.Exception) in C#

 📌 System.Exception is the base class for all exceptions in C#.


 📌 It provides a foundation for handling and defining errors.
 📌 Every built-in and custom exception inherits from System.Exception.

C# has a large set of built-in exceptions, organized under the System.Exception


hierarchy. Exceptions are classified based on their usage and severity.

Below is a comprehensive list of all major exceptions in C#:

🔹 4.1.1 Root Exception Class

 Exception → The base class for all exceptions.

🔹 4.1.2. System-Level Exceptions (SystemException)

 SystemException → Base class for system-related exceptions.

🟢 Common System Exceptions:

 NullReferenceException → Using an object reference that is null.

sing System;

class Program
{
static void Main()
{
try
{
string text = null;
Console.WriteLine(text.Length); // ❌ NullReferenceException
}
catch (NullReferenceException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}

24
}
}

🔹 Explanation text is null, so calling .Length on it triggers a NullReferenceException.

 IndexOutOfRangeException → Trying to access an array outside of its bounds.


 InvalidOperationException → When an operation is invalid in the current state.
 StackOverflowException → Infinite recursion causes a stack overflow.
 OutOfMemoryException → When the system runs out of memory.
 AccessViolationException → Trying to access protected memory.
 FormatException → Invalid format for data conversion (e.g., parsing a string as an
integer).
 TypeInitializationException → Error occurs when initializing a static type.
 NotImplementedException → When a method is declared but not implemented.
 NotSupportedException → When an operation is unsupported.

🔹4.1. 3. Argument Exceptions (ArgumentException)

 ArgumentException → Base class for argument-related exceptions.

🟢 Specific Argument Exceptions:

 ArgumentNullException → A method argument is null but shouldn't be.


 ArgumentOutOfRangeException → A parameter is outside the allowed range.

🔹4.1. 4. Arithmetic and Mathematical Exceptions (ArithmeticException)

 ArithmeticException → Base class for math-related exceptions.

🟢 Specific Arithmetic Exceptions:

 DivideByZeroException → Division by zero

Occurs when dividing a number by zero.


Example
csharp
using System;

class Program
{
static void Main()
{
try
{

25
int result = 10 / 0; // ❌ DivideByZeroException
}
catch (DivideByZeroException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}

🔹 Explanation Division by zero is not allowed, so the exception is triggered.

 OverflowException → Numeric operation exceeded the allowed range.

🔹4.1. 5. Input/Output Exceptions (IOException)

 IOException → Base class for input/output errors.

🟢 Specific IO Exceptions:

 FileNotFoundException → File not found.


 DirectoryNotFoundException → Directory not found.
 PathTooLongException → File path exceeds the maximum allowed length.
 UnauthorizedAccessException → No permission to access a file.
 EndOfStreamException → End of a data stream is unexpectedly reached.
 DriveNotFoundException → The specified drive does not exist.

🔹4.1. 6. Reflection and Type Exceptions

 TypeLoadException → Error loading a type.


 MissingMethodException → A method was expected but doesn't exist.
 MissingMemberException → A class member was expected but doesn't exist.
 TargetInvocationException → When a method invocation fails in reflection.

🔹4.1. 7. Security Exceptions

 SecurityException → Violations of security permissions.

🔹 4.1.8. Threading and Concurrency Exceptions

 ThreadAbortException → When a thread is aborted.


 ThreadInterruptedException → When a thread is interrupted.
 SynchronizationLockException → When synchronization is incorrectly used.
 TimeoutException → When an operation takes longer than expected.

26
🔹4.1. 9. Database-Related Exceptions

 DbException → Base class for ADO.NET database exceptions.


 SqlException → Issues related to SQL Server queries.

Occurs during SQL operations with incorrect queries or connection issues.

Example

using System;
using System.Data.SqlClient;

class Program
{
static void Main()
{
try
{
string connectionString = "InvalidConnectionString";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open(); // ❌ SqlException
}
}
catch (SqlException ex)
{
Console.WriteLine($"Database Error: {ex.Message}");
}
} 🔹 Explanation Trying to open an invalid database connection causes an
exception.

 DataException → General data-access-related error.


 ConstraintException → When a database constraint fails.
 InvalidConstraintException → When a database constraint is violated.

🔹4.1. 10. Serialization Exceptions

 SerializationException → Errors occurring during serialization.

🔹4.1. 11. Networking Exceptions

 WebException → Network error (e.g., failed HTTP request).

27
 SocketException → Error in network socket communication.

4.1.12 Purpose of System.Exception

🔹 Standardizes error handling in C#.

🔹 Allows developers to catch and process exceptions easily.

🔹 Enables applications to continue running despite errors.

🔹 Supports exception chaining using InnerException.

4.1.13 Key Properties of System.Exception

 Message → Stores the error description.


 StackTrace → Shows where the error originated.
 InnerException → Stores nested exceptions for debugging.
 Source → Identifies the assembly or application causing the error.
 Data → Stores additional information as key-value pairs.

Example:

try

throw new Exception("A basic exception occurred.");

catch (Exception ex)

Console.WriteLine($"Error: {ex.Message}");

Console.WriteLine($"Stack Trace: {ex.StackTrace}");

4.1.14 Constructors of System.Exception

 Default Constructor → Creates an empty exception.

28
 Parameterized Constructor → Accepts a custom error message.
 Constructor with InnerException → Wraps another exception inside.

Example:

try

throw new Exception("Primary exception.");

catch (Exception ex)

throw new Exception("Secondary error occurred.", ex);

4.1.15 Common Methods in System.Exception

 🔍 ToString() → Returns a string representation of the exception.


 🔍 GetBaseException() → Retrieves the root cause of the error.
 🔍 HelpLink → Stores a link to additional help resources.

Example:

try
{
throw new Exception("Main error.");
}
catch (Exception ex)
{
Console.WriteLine(ex.GetBaseException().Message);
}
4.2 Checked vs. Unchecked Exceptions

Checked vs. Unchecked Exceptions in C#

 📌 C# does not enforce checked exceptions like Java.

29
 📌 Exceptions in C# are runtime exceptions—handled dynamically.
 📌 Checked vs. Unchecked exceptions help classify errors for better handling.

4.2.1 Checked Exceptions

 🔹 Checked exceptions occur due to external issues (e.g., file or network failures).
 🔹 They must be handled using try-catch to prevent program failure.
 🔹 Examples include:
o FileNotFoundException → Occurs when a file is missing.
o IOException → Happens due to I/O operation failures.
o FormatException → Invalid input format errors.

Example:

try
{
int number = int.Parse("InvalidData");
}
catch (FormatException ex)
{
Console.WriteLine("Handled FormatException: " + ex.Message);
}
4.2.2 Unchecked Exceptions

 🔹 Unchecked exceptions arise due to coding mistakes (e.g., null references).


 🔹 They are not enforced by the compiler but occur at runtime.
 🔹 Examples include:
o NullReferenceException → When accessing an object that is null.
o IndexOutOfRangeException → When exceeding array limits.
o DivideByZeroException → Division by zero errors.

Example:

try
{
int result = 5 / 0; // Causes DivideByZeroException
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Handled: " + ex.Message);
}

Key Differences

30
✅ Checked Exceptions → Must be caught or handled explicitly. ✅ Unchecked Exceptions →
Occur due to programming errors. ✅ Checked Exceptions → Typically result from external
sources. ✅ Unchecked Exceptions → Occur due to incorrect logic in code.

4.3 Exception Inheritance Structure

5. Handling Multiple Exceptions


 Using Multiple catch Blocks

 Filtering Exceptions Using catch when

 Nested Try-Catch Blocks

5.1 Using Multiple catch Blocks in C#


 📌 catch blocks allow handling multiple exception types separately.
 📌 Each catch block targets a specific exception based on type.
 📌 If an exception matches a catch block, that block executes.
 📌 If no matching catch block exists, the exception remains unhandled.
31
Key Benefits of Using Multiple catch Blocks
 🔹 Enables precise error handling for different exception types.
 🔹 Reduces reliance on generic exception handling (Exception).
 🔹 Prevents overgeneralization of exceptions, improving debugging
clarity.
 🔹 Allows developers to respond differently to various failure
scenarios.
Basic Syntax of Multiple catch Blocks
csharp
try
{
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[5]); // Causes IndexOutOfRangeException
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("Handled: Array index out of range.");
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Handled: Division by zero detected.");
}
catch (Exception ex)
{
Console.WriteLine("Handled: General exception occurred.");
}
Execution Flow of Multiple catch Blocks
 ✅ The first matching catch block executes, skipping others.
 ✅ Exception order matters—more specific exceptions should be
caught first.
 ✅ A general catch block (Exception) should come last to handle
unknown exceptions.
Example Flow:

try
{
int num = 5 / 0; // Causes DivideByZeroException
}
catch (DivideByZeroException ex) // ✅ First match (executes)
{

32
Console.WriteLine("Error: Cannot divide by zero.");
}
catch (Exception ex) // ❌ Skipped (already handled above)
{
Console.WriteLine("General Exception caught.");
}
Order of catch Blocks Matters
 ✅ Start with specific exceptions, moving to general ones.
 ✅ Avoid placing Exception first, as it catches all errors.
 ✅ Prioritize critical exceptions before broader ones.
Example of Incorrect Order:
csharp
try
{
int num = int.Parse("abc"); // Causes FormatException
}
catch (Exception ex) // ❌ First catch block (catches everything)
{
Console.WriteLine("General Exception caught.");
}
catch (FormatException ex) // ❌ Never executes (already caught above)
{
Console.WriteLine("FormatException handled.");
}
Example of Correct Order:
csharp
try
{
int num = int.Parse("abc"); // Causes FormatException
}
catch (FormatException ex) // ✅ Catches first (executes)
{
Console.WriteLine("Handled: Invalid number format.");
}
catch (Exception ex) // ✅ Executes only if previous blocks fail
{
Console.WriteLine("Handled: General Exception.");
}

33
5.2 Filtering Exceptions Using catch when in C#
 📌 catch when allows filtering exceptions based on specific conditions.
 📌 Unlike regular catch, it executes only when the condition is true.
 📌 Helps in dynamic exception handling by applying logic to errors.
 📌 Reduces unnecessary exception handling when certain criteria are
met.
Key Features of catch when
 🔹 Conditional Handling → Executes only when the specified condition
matches.
 🔹 Selective Exception Processing → Skips exceptions that don't
meet the criteria.
 🔹 Refines Error Handling → Avoids catching errors that don't need
to be processed.
 🔹 Improves Debugging → Provides better control over when
exceptions are handled.
Basic Syntax of catch when
try
{
int number = int.Parse("InvalidData"); // Causes FormatException
}
catch (FormatException ex) when (ex.Message.Contains("Input string"))
{
Console.WriteLine("Filtered Exception: Invalid format detected.");
}
catch (Exception ex)
{
Console.WriteLine("General Exception caught.");
}
How catch when Works
 ✅ The condition inside when evaluates the exception details.
 ✅ If the condition is true, the exception is handled.
 ✅ If the condition is false, the exception bypasses the block and
moves to the next catch.
Example Flow:
try
{
throw new ArgumentException("Invalid Argument");
}
catch (ArgumentException ex) when (ex.Message.Contains("Invalid"))

34
{
Console.WriteLine("Handled: Argument Exception.");
}
catch (Exception ex)
{
Console.WriteLine("Unhandled: General Exception.");
}
Real-World Use Cases of catch when
✅ Logging Specific Exceptions → Only log critical errors, skipping minor
ones. ✅ Retry Mechanisms → Handle exceptions based on failure count. ✅
Network Errors → Catch connection errors only when retry attempts exceed
a limit. ✅ Security Filtering → Handle access-related errors based on user
roles.
Example:
int retryCount = 3;

try
{
throw new Exception("Connection failed.");
}
catch (Exception ex) when (retryCount > 2)
{
Console.WriteLine("Handled: Network error after multiple retries.");
}

.5.3 Basic Nested Try-Catch Block


 Outer try-catch handles overall exceptions.
 Inner try-catch catches specific errors inside the block.
 The inner exception can be re-thrown to be handled at a higher level.
csharp
try
{
Console.WriteLine("Starting outer try block.");

// Inner try-catch for specific errors


try
{
int result = 5 / 0; // Causes DivideByZeroException
}

35
catch (DivideByZeroException ex)
{
Console.WriteLine("Inner Catch: Division by zero error.");
throw; // Re-throws exception to outer catch block
}

Console.WriteLine("This line is skipped after an inner error.");


}
catch (Exception ex)
{
Console.WriteLine("Outer Catch: Handling re-thrown exception.");
}

Console.WriteLine("Program execution continues after exception handling.");


💡 Description:
 throw; inside the inner catch passes the exception to the outer
block.
 The outer catch handles any re-thrown exceptions and ensures
program continuation.
2. Nested Try-Catch Handling Different Exceptions
 Different types of exceptions are caught at different levels.
 IndexOutOfRangeException occurs in the inner block.
 Outer block ensures final handling of uncaught exceptions.
csharp
try
{
Console.WriteLine("Outer try block begins.");

try
{
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[5]); // Causes IndexOutOfRangeException
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("Inner Catch: Array index out of bounds.");
throw; // Exception passed to outer block
}

Console.WriteLine("Outer try block resumes.");

36
}
catch (Exception ex)
{
Console.WriteLine("Outer Catch: Handling thrown exception.");
}
💡 Description:
 Inner try block throws an IndexOutOfRangeException.
 Inner catch handles it but re-throws it using throw;.
 Outer catch then catches the error and handles it properly.
3. Deeply Nested Try-Catch Blocks
 Errors bubble up through multiple nested levels.
 Each level of catch handles errors and can choose to re-throw or
suppress them.
csharp
try
{
Console.WriteLine("Executing outer try block.");

try
{
try
{
throw new NullReferenceException("Inner-most error");
}
catch (NullReferenceException ex)
{
Console.WriteLine("Innermost Catch: Handling
NullReferenceException.");
throw; // Passes the error up one level
}
}
catch (Exception ex)
{
Console.WriteLine("Middle Catch: Caught an exception and re-
throwing.");
throw; // Passes the error up to the outer block
}
}
catch (Exception ex)
{

37
Console.WriteLine("Outer Catch: Final handling of exception.");
}

Console.WriteLine("Program execution resumes after handling exceptions.");


💡 Description:
 Innermost block throws a NullReferenceException.
 The middle block catches it, logs an error message, and passes it
up.
 The outer block catches the final exception, ensuring complete
error handling.

6. Creating and Using Custom Exceptions


 Defining Custom Exception Classes

 Implementing Custom Exception Handling

 Adding Custom Properties and Methods

6.1 Definition of a Custom Exception Class in C#


 📌 A custom exception is a user-defined error class that extends
the built-in Exception class.
 📌 It is used to handle application-specific error conditions that
built-in exceptions do not cover.
 📌 Custom exceptions improve code readability, debugging, and
error classification.
 📌 They allow developers to define specialized exception types with
custom properties and behaviors.
 📌 A custom exception must inherit from Exception or a derived class
like System.ApplicationException (deprecated).

6.2 Implementation of Custom Exception Handling in C#


using System;

class Program
{
static void Main()
{
try
{
ValidateAge(15); // Call method that throws a custom exception

38
}
catch (AgeValidationException ex)
{
Console.WriteLine($"Custom Exception Caught: {ex.Message}");
}
}

static void ValidateAge(int age)


{
if (age < 18)
{
throw new AgeValidationException("Age must be 18 or older.");
}
Console.WriteLine("Age is valid.");
}
}

// Custom exception class


public class AgeValidationException : Exception
{
public AgeValidationException(string message) : base(message) { }
}
💡 Explanation:
 🔹 Custom Exception Class (AgeValidationException) is defined by
inheriting from Exception.
 🔹 ValidateAge Method throws the custom exception if age is below 18.
 🔹 try-catch Block in Main handles the custom exception when thrown.

6.3 Adding Custom Properties and Methods to a Custom Exception


in C#
using System;

// Custom exception class with additional properties and methods


public class AgeValidationException : Exception
{
// Custom property
public int InvalidAge { get; }

// Constructor with custom property initialization

39
public AgeValidationException(string message, int age) : base(message)
{
InvalidAge = age;
}

// Custom method to get formatted error details


public string GetExceptionDetails()
{
return $"Error: {Message}, Invalid Age: {InvalidAge}";
}
}

// Main program demonstrating exception handling with custom properties


and methods
class Program
{
static void Main()
{
try
{
ValidateAge(15); // Passing an invalid age
}
catch (AgeValidationException ex)
{
Console.WriteLine($"Custom Exception Caught:
{ex.GetExceptionDetails()}");
}
}

// Method that throws the custom exception


static void ValidateAge(int age)
{
if (age < 18)
{
throw new AgeValidationException("Age must be 18 or older.", age);
}
Console.WriteLine("Age is valid.");
}
}
Explanation of Key Enhancements in the Custom Exception Class

40
 📌 Custom Property (InvalidAge) → Stores the invalid age that caused
the exception.
 📌 Parameterized Constructor → Initializes both exception
message and custom property.
 📌 Custom Method (GetExceptionDetails) → Returns detailed error
information.
 📌 Exception Handling in try-catch Block → Retrieves custom error
details using a method.
Benefits of Adding Custom Properties and Methods
✅ Enhances debugging → Developers can track the exact value causing an
error. ✅ Provides structured error information → Messages are more
informative than generic ones. ✅ Encapsulates custom logic → Methods
define reusable exception-handling behaviors. ✅ Supports advanced error
logging → Easy to log detailed exception data in real-world applications.

7. Exception Propagation and Best Practices


 Exception Propagation Across Methods

 Best Practices in Exception Handling

 Writing Meaningful Error Messages

 Avoiding Overuse of Try-Catch Blocks

7.1 Exception Propagation Across Methods


 📌 Exception propagation refers to how exceptions move from one
method to another.
 📌 When a method encounters an exception, it can either handle it or
propagate it to the caller.
 📌 If an exception is not caught in the current method, it moves up the
call stack.
 📌 This allows higher-level methods to handle exceptions more
effectively.
Example:

void MethodA()
{
MethodB(); // Calls MethodB, which throws an exception
}

41
void MethodB()
{
throw new Exception("Error occurred in MethodB."); // Unhandled
exception propagates
}

MethodA(); // Exception moves up to the main caller


💡 Key takeaway: If MethodB does not catch the exception, it propagates
to MethodA, which must handle it.

7.2 Best Practices in Exception Handling


✅ Use specific exception types instead of catching Exception. ✅
Implement meaningful error messages to improve debugging. ✅ Log
exceptions properly using logging frameworks like Serilog or NLog. ✅ Use
finally blocks for cleanup operations like closing database connections. ✅
Avoid swallowing exceptions by keeping empty catch blocks. ✅ Ensure
exception propagation when a lower-level method cannot handle the error
properly.
Example of logging exceptions:
try
{
throw new InvalidOperationException("Invalid operation performed.");
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"Error: {ex.Message}"); // Log exception details
}

7.3 Writing Meaningful Error Messages


 Error messages should clearly describe the problem.
 Avoid generic messages like "Something went wrong"—make it
specific.
 Provide context in messages, such as method names or failed
conditions.
 Error messages should help debugging, not confuse developers.
Example:
csharp
throw new ArgumentException("User age cannot be negative. Please provide
a valid age.");

42
💡 Key takeaway: A well-written message immediately tells what the issue
is and how to fix it.

7.4 Avoiding Overuse of Try-Catch Blocks


❌ Do not wrap every block of code in try-catch unnecessarily. ❌ Use
exceptions for unexpected errors, not for control flow. ❌ Rely on
validations instead of throwing exceptions for simple checks. ❌ Only catch
exceptions where handling is required—let unhandled exceptions
propagate if needed.
Example of overuse (bad practice):
try
{
if (age < 0)
throw new ArgumentException("Invalid age."); // Unnecessary exception
}
catch (ArgumentException ex)
{
Console.WriteLine("Handled error: " + ex.Message); // Could be avoided
with validation
}
Example of good practice:
csharp
if (age < 0)
{
Console.WriteLine("Age cannot be negative."); // Prevent exception using
validation

8. Exception Handling in Delegates and Events


 Managing Exceptions in Event-Driven Programming

 Exception Handling in Callback Functions

8.1 Managing Exceptions in Event-Driven Programming


 📌 In event-driven programming, exceptions can occur inside event
handlers.
 📌 If an event handler throws an exception, it may disrupt the event
execution flow.
 📌 Unhandled exceptions in event-driven systems may cause the
program to crash unexpectedly.

43
 📌 Exception handling ensures that errors in event handlers do not
affect other subscribers.
 📌 Best practices include catching exceptions within event handlers
and using logging mechanisms.
Example:
csharp
public class EventPublisher
{
public event EventHandler MyEvent;

public void RaiseEvent()


{
try
{
MyEvent?.Invoke(this, EventArgs.Empty);
}
catch (Exception ex)
{
Console.WriteLine($"Exception in event handler: {ex.Message}");
}
}
}
💡 Key takeaway: Exceptions inside event handlers should be caught to
prevent breaking the event invocation process.

8.2 Exception Handling in Callback Functions


 📌 Callback functions are methods passed as arguments to other
functions for execution.
 📌 If a callback function throws an exception, it may disrupt the
execution of the calling function.
 📌 Exception handling ensures that errors do not affect subsequent
callbacks.
 📌 Wrapping callback execution in a try-catch block prevents program
crashes.
 📌 Logging errors inside the callback helps debugging without
stopping execution.
Example:
public delegate void CallbackDelegate(string message);

public class CallbackHandler

44
{
public void ExecuteCallback(CallbackDelegate callback)
{
try
{
callback("Executing callback function...");
}
catch (Exception ex)
{
Console.WriteLine($"Exception in callback: {ex.Message}");
}
}
}

9. Global Exception Handling in C#


 Using AppDomain.UnhandledException

 Implementing Global Exception Handling in Web Applications (ASP.NET)

9.1 Using AppDomain.UnhandledException in C#


• Using AppDomain.UnhandledException • Implementing Global Exception
Handling in Web Applications (ASP.NET)
Using AppDomain.UnhandledException in C#
 📌 AppDomain.UnhandledException provides a global error-handling
mechanism for unhandled exceptions.
 📌 It catches exceptions that are not handled in any try-catch block,
preventing program crashes.
 📌 This handler is useful in console applications and desktop
applications for centralized exception management.
 📌 Setting up an UnhandledException event helps log errors before the
application exits.
Example:
class Program
{
static void Main()
{
AppDomain.CurrentDomain.UnhandledException +=
GlobalExceptionHandler;

throw new Exception("Unhandled error!");

45
}

static void GlobalExceptionHandler(object sender,


UnhandledExceptionEventArgs e)
{
Console.WriteLine($"Global Exception Caught:
{((Exception)e.ExceptionObject).Message}");
}
}
💡 Key takeaway: Exceptions not handled elsewhere will trigger this global
handler, preventing unexpected application termination.

9.2 Implementing Global Exception Handling in Web Applications


(ASP.NET)
 📌 In ASP.NET applications, global exception handling ensures all
unhandled errors are logged and managed centrally.
 📌 It prevents users from seeing raw system errors and redirects them
to an error page.
 📌 Common methods for handling exceptions globally in ASP.NET:
o Middleware Exception Handling (UseExceptionHandler)
o Custom Error Handling in Global.asax
o Exception Filters (IExceptionFilter)
Example using middleware (UseExceptionHandler):
public void Configure(IApplicationBuilder app)
{
app.UseExceptionHandler("/ErrorPage"); // Redirects to error page on
exception
}
Example using global filters in ASP.NET Core:
csharp
public class GlobalExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
context.Result = new ObjectResult("Global error handled.")
{ StatusCode = 500 };
}
}

46
10. Debugging and Error Recovery Strategies
 Using Debuggers (Visual Studio Exception Settings)

 Graceful Degradation and Recovery

10.1 Using Debuggers (Visual Studio Exception Settings)


 📌 Debuggers help developers track and fix errors efficiently in C#.
 📌 Visual Studio Exception Settings allow customizing exception
handling.
 📌 Developers can enable breaking on specific exceptions, skipping
handled exceptions, and setting custom debugger rules.
 📌 Breakpoints & Watch Windows help monitor variable values at
runtime for deeper analysis.
 📌 Exception Settings Window in Visual Studio allows choosing when
exceptions should break execution.
Example debugging steps in Visual Studio: 1️⃣ Open Exception
Settings (Debug → Windows → Exception Settings). 2️⃣ Enable specific
exceptions to break execution when thrown. 3️⃣ Use the Immediate
Window (Ctrl+D, I) to test and evaluate expressions. 4️⃣ Set conditional
breakpoints for debugging particular error scenarios.
💡 Key takeaway: Debuggers provide better visibility into where and why
exceptions occur, helping improve application reliability.

10.2 Graceful Degradation and Recovery


 📌 Graceful degradation ensures a system continues functioning
despite errors.
 📌 Applications should prevent crashes by intelligently handling
unexpected errors.
 📌 Recovery strategies include fallback mechanisms, default values,
and retry attempts.
 📌 A common practice is logging exceptions while keeping essential
functionality accessible.
 📌 Recovery can involve retrying failed operations or switching to a
safer execution mode.
Example of graceful error recovery:
csharp

47
try
{
int result = 10 / 0; // Causes DivideByZeroException
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Error detected, switching to safe mode.");
int result = 1; // Fallback value to maintain program stability
}

11 Summery
Exception handling in C# is a vital feature that ensures applications remain
stable and responsive even when unexpected errors occur. By using try,
catch, finally, and throw blocks, developers can structure their code to
detect, manage, and recover from runtime issues effectively.
Through proper implementation of exception handling, software becomes
more reliable and maintainable, reducing the risk of abrupt failures.
Understanding the hierarchy of exceptions and leveraging built-in exception
classes allows developers to address errors efficiently while providing
meaningful feedback to users.
Effective exception handling practices, such as using specific exception
types, logging errors, and avoiding excessive catch blocks, contribute to a
well-structured and resilient application. By mastering these techniques,
developers can build software that adapts to various runtime challenges
while ensuring a smooth user experience.

48
12 References
1. Microsoft Docs. (2023). Exception Handling (C# Programming Guide).
[https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/
exceptions/](https://learn.microsoft.com/en-us/dotnet/csharp/programming-
guide/exceptions/)

2. Microsoft Docs. (2023). Debugging in Visual Studio.


[https://learn.microsoft.com/en-us/visualstudio/debugger/](https://
learn.microsoft.com/en-us/visualstudio/debugger/)

3. Troelsen, A., & Japikse, P. (2022). Pro C# 10 with .NET 6. Apress.


- Chapter 7: "Exception Handling and Debugging."

4. Richter, J. (2012). CLR via C# (4th ed.). Microsoft Press.


- Chapter 20: "Exceptions and State Management."

5. McConnell, S. (2004). Code Complete: A Practical Handbook of Software


Construction(2nd ed.). Microsoft Press.
- Section on Defensive Programming and Error Handling.

6. Freeman, A., & Jones, A. (2021). *C# 10 and .NET 6 – Modern Cross-
Platform Development. Packt.
- Chapter 4: "Debugging and Exception Handling."

49

You might also like