In the previous lab we discussed about the various basic points to remember about C# Strings. Now today in this lab we will discuss about another important thing about C# Exceptions.

C# Exceptions:

First of all we will understand what do we mean by exception? If we try to understand simple English meaning of exception it says that, someone or something does not follow any rules or is excluded from general things. But exceptions in C# have a bit different meaning from the general meaning.

So exceptions in C# can be defined as some event or we can say bad event which disrupts the normal flow of our application. Now normal flow of the application means for example we have some task where we want to divide two numbers and display it on the screen, so when we run this task it will divide the two numbers and will display it on the screen. This is the normal flow but now suppose if we divide one number with zero then it will give us an exception and will disrupt our task. It will give us a Divide by zero exception.

b1

Its exception is given as follows,

b2

This is how exception is shown, but in a real software application there are going to be many exceptions. So the most important thing is that have we handled the exceptions or not. Now the above example also has an exception and we will see how we will be able to handle it.

Now what happens if the exceptions are not handled, some code will throw all the unhandled exceptions to our .NET framework. The .NET framework will then show that error to us on the screen as we saw in the above image. And this error will be shown in a very unorganized or shabby manner.

So now to handle the exception and show the error message on the screen in a very organized manner we will use,

Try Block: It is an area where we know or we expect the exception would occur. For the above example we know that dividing 10 with 0 will give us an exception, so for this reason we use try block wherever we expect the error would occur.

Catch Block: It is used to catch the error or the exception occurred in the try block. So what happens is that when the exception occurs in the try block, it will send the control of the program to the catch block and in the catch block we will give a simple error message.

b2

b4

It has shown us a neat and organized error message.

Now what happens is that we have here shown a generic message but we also want to show the message saying what kind of exception occurred. The previous message was shabby and unorganized but it still showed that the exception is a divide by zero exception. To show the exception message along with the reason why it occurred, we can use the message property of the exception instead of giving any generic message. The command for it is,

catch (Exception ex)
            {
Console.WriteLine(ex.Message);
            }

And its output will be,

b5

Now after getting the proper error message, there is one problem where after the divide method there is a “Thank You” message which is not being displayed. Now we want to display our “Thank You” message irrespective of the exception occurring or not.

Now if we try to run the above program by putting debug points to see how the flow is going, we can see that after the exception is occurred it directly goes to the catch block and display the error message. It means that the code written after the exception is by passed. So another point to remember in C# Exceptions is that the point where the exception is occurred after that if we have any code written that code will not be executed.

But now if we want that code to be executed in this case our “Thank You” message irrespective of the exception occurred or not we will use something called as Finally Block.

Finally Block: It helps us to display the message or any code in our program irrespective of the exception occurred or not. In short this block will run whether the exception is there or not.

b6

b7

b8

b9

Now one more important thing about C# Exceptions is that they propagate from source to the caller or we can say callee to caller. Here in the above example we add one more function named Arithmetic and this function takes two numbers and internally it calls the same divide function. So we can say the Arithmetic is a wrapper around the Divide function. So what will happen is that if any exception occurs it will throw the exception to the arithmetic function and it will further throw it to the Main function until the exception is handled.

b10

Here in the above image we see the flow where the Main function will call the Arithmetic function and Arithmetic function will call the Divide function.

b11

The output will be the same as it was for the previous one.

b12

Now there is a problem with the exceptions propagating. In our project we make many layers like UI, Business Logic, Data Layer, etc. and now if the exception occurs in any of the layer it will get propagated and when we are in production we want to know in which layer the exception has occurred. So in our above example we want to know whether our exception has occurred on the Divide or the Arithmetic. For that we have a simple code,

Console.WriteLine(ex.StackTrace);

Instead of showing Message we use Stack Trace. It displays how the call happened and where the error happened. So if we run the code we will get the following output.

b13

b14

Here the exception was occurred at Divide and then it was thrown to the Arithmetic and after that as the exception was still not handled it was thrown to the Main where it was handled. So in short Stack Trace tells us how the whole call happened and exactly in which layer the exception occurred.

So till now whatever exception we saw all of that was provided by our .Net system. So in the above example the .Net system threw divide by zero exception. So what now if we want to throw our own exceptions. We can create our user defined exception,

b15

Now if our inputs are 10 & 0 then our output will show divide by zero exception as we saw in the above example, but if our inputs are -1 & 0 then it will give us our custom defined exception message.

b16

In this way we can define and create our own exceptions. So if we want to throw our own exceptions then we have to use the “throw” keyword.

Now in the above example we have two types of exception one is “Divide by zero exception” given by .Net system and other is “Negative numbers not allowed” created by us. So there are two types of exception but there is only one Catch block to catch these exceptions. It is like a generic Catch block for all kinds of exception. But now we want to handle both of these exceptions specifically. To do that we can create multiple Catch blocks.

b17

Here we have created a new Catch block which will handle “Divide by zero exception”. So if we put the input as 10 & 0 then output will be,

b18

And if the inputs are -1 & 0 the output will be,

b19

So both the exceptions are handled by specifically by creating multiple Catch blocks.

Now one more important thing to remember is that our generic exceptions should be at the bottom of the sequence. It means that there are many types of exceptions given by our .Net systems and all of these exceptions inherit from the parent class known as system.Exception. If we put the parent exception in the beginning then it will bypass all the other child exceptions. So make sure that we have to keep our parent or generic exception at the end of our sequence and all the other child exceptions at the top.

Now sometimes it happens that we have created one or more user defined exceptions and these exceptions are handled by only one Catch block which gives generic message. For differentiating between the two user defined exceptions we have to create our own exception class.

b20

b21

Now if the inputs are 1&1 then the output will be,

b22

If the inputs are 1&0 the output will be, “divide by zero not possible” and if the inputs are -1&0 then the output will be “negative numbers are not allowed”.

Exception Swallowing:

Now sometimes what happens we create a Try Catch block in our middle layer and inside the Catch we create our own exception and give a generic message. So what happens is that when the exception is propagated from source to caller in this case from Divide to Arithmetic to Main, the middle layer i.e. Arithmetic will catch all the exceptions and give the generic message for all the exceptions whether they are from .Net system or our own created exceptions.

So what we have to do is that instead of creating the new exception we throw the exception to the caller in this case Main.

Instead of

catch (Exception ex)
            {
thrownewException("Something bad happened");
            }
We will write,
catch (Exception ex)
            {
throw ex;
            }

What this code will do is that the exception coming from Divide function to Arithmetic function, it will be thrown toward Main function.

Therefore, as a best practice avoid “throw new Exception” until we want to add something new to it along the propagation chain or else the best is to say “throw ex” i.e. basically whatever is in the stack , throws it to the top. This is termed as Exception Swallowing.

Following is the beginner video to learn C# for fresher’s who wants to pursue carieer as programming; –

Advertisements