Join Gerry O'Brien for an in-depth discussion in this video Throwing exceptions, part of Learning C#.
When working with structured exception handling in your C Sharp application, there may be times where you don't want to handle the exception in the function in which it was generated. A good example of this might be, where you have written exception handling routines that are responsible for writing out the specific exception information to log files that you can then review later on and determine why the application crashed. The example that we're going to show here is relatively simple. It's not dealing with any logging information or writing out to any files, but we have a structured exception handling process set up within our code. We actually have two exception handling routines. One in the main method, and one within the divide method. And, the reason that I've set it up this way is to show you an example of how you can throw your own exceptions back up the call stack, and also provide more specific information than what the .Net framework exception classes provide. This would be an example of you providing more detailed information to write into some kind of an exception log or an application log, that allows you to troubleshoot a little bit later on. So what we have here is in the main method, we're going to collect an error message here as well for output in whichever routine or whichever exception handler catches this. And in our case, it's going to be the DivideByZeroException. We wrap our Divide function within one triblock, so that we can catch any exceptions that are thrown from that.
We look for a specific exception, such as Overflow, DivideByZero, and then the generic Exception, and then we output the appropriate message to the console. This Console.WriteLine would be where you would put in the code to write out to your log files for your application. As we look at the divide method, it's relatively simple. If you've been viewing the course all the way through from beginning to end, you will have seen this already. We have a numerator, a denominator and a result. We prompt for input for the numerator and the denominator, and then we take our protected code, we wrap it in a triblock and we look for some kind of an exception that may happen in here. And we will actually purposely generate the DivideByZero exception. And then, we catch the DivideByZero exception here. Now, when we look at it from the perspective of what happens up in this code here, we're also checking for Overflow DivideByZero and generic Exception. Ultimately, we don't require this code here at all because we're going to collect the generic Exception that takes place, and the reason being, you'll see in a moment, is I'm going to write a throw statement that just creates a new generic Exception. So as we come back down into our divide method, when we attach this DivideByZeroException, we need to do something to handle it, so we need to write code that is going to do something. We could write out to the log file in here but instead, we're going to envision having a routine that writes out to a log file. So we want to throw this exception back up the call stack. And how we do that is through the use of the keyword throw. So, we're going to write out the keyword throw and, in order to throw an exception, we have to create a new exception class. We're going to throw a new Exception, and this is a generic Exception class, and it's also what we refer to as an overloaded function, or an overloaded method because the Exception class has three different constructors. It says two overloads but as you can see there's three items here. We can initialize it just as a new Exception and throw it and it initializes a new instance of that class, or we can initialize it with a string with a message, so a message that describes the error, or we can include a message, but that also add another inter exception, and the inter exception is the one that caused the exception itself. So in this instance, I'm going to use this third overload for the constructor of the exception class and the reason being is that I'm assuming again that I want to write to a log file, and the information I'm going to send out, I want to provide more specific information to the user, which will be output on the screen. But also at the same time, I want to write that information to the log file along with the actual exception that the .Net framework generated. So, my string message that I'm going to put in here would be one that would be more user friendly, if you will, to people using the application and I'll say that DivideByZero is not permitted, please let's say that we want them to change. So please change the denominator, and that should be sufficient for now. You can envision perhaps, writing more information in here that would be to the log file that may be the application name, the time of day that it occurred, et cetera, et cetera, so you could put all kinds of information in this string message. And then we also want to include in this instance the specific inner exception. So we had a divide by zero exception and we want to add that inner exception information that occurred. So we get that specific information from the .Net framework as well. So, now we've written this throw statement. We're throwing a new Exception. We'll pass it back up to call stack, in which case it should be caught in this triblock, and it should come down through, actually fall all the way through this exception handling catch phrase here, and then we will output that information to the screen. So control F5 to execute the application. Let's throw in a number 45, put zero in to generate that DivideByZero exception, and you can see that we actually get our Division by zero is not permitted, please change the denominator. This is our custom message and this was the way we created it was through that throw method. Press any key obviously and the application exits itself. So again, using the throw keyword is a great way for you to rethrow an exception, backup the call stack so that it can be handled someplace else in the application. Primarily, you might use that if you have a specific set of classes that are designed to handle exceptions and write that information out to a log file.
- Installing C#
- Working with loops
- Controlling program flow
- Using variables
- Building functions
- Creating and instantiating classes
- Catching errors
- Managing resources with the garbage collector
- Building collections