WEBVTT

00:00.180 --> 00:05.520
Hello again! In this video, we are going to look at the exception mechanism. So what actually happens

00:05.520 --> 00:06.930
when an exception is thrown?

00:07.650 --> 00:11.070
And we are also going to find out how to re-throw an exception.

00:13.630 --> 00:17.140
When an exception is thrown, several things happen.

00:17.860 --> 00:23.890
First of all, the exception object, which is being thrown, that gets copied into a special area of

00:23.890 --> 00:26.740
memory, which is not part of the local stack.

00:27.400 --> 00:34.060
This area in memory is set up by the compiler and any catch block which can handle that exception type

00:34.360 --> 00:36.400
is able to access that memory.

00:36.790 --> 00:41.110
So that is how the exception object gets transferred from one part of the program to the other.

00:43.970 --> 00:49.550
Every local variable in this scope is destroyed, which includes the original copy of the thrown object.

00:50.210 --> 00:55.280
And the program will immediately leave this scope, without executing any further instructions.

00:55.700 --> 00:58.760
So this is rather like having a return statement in a function call.

01:01.480 --> 01:06.910
The program is then going to look for a catch block, to handle the exception. If the exception is thrown

01:06.910 --> 01:10.960
in a try block, it is going to look in the catch blocks which follow after that try block.

01:12.010 --> 01:16.690
If it cannot find one, it is going to destroy all the local variables and exit this current scope.

01:19.530 --> 01:25.740
So if you imagine the call stack, we have this stack of function calls. And the program's exception

01:25.740 --> 01:32.010
handling mechanism is going to go up this stack, looking for a suitable handler, and cleaning the stack

01:32.010 --> 01:32.760
up as it goes.

01:33.510 --> 01:37.560
If it gets all the way to main() without finding one, then the program is terminated.

01:38.580 --> 01:44.340
And this process of repeatedly destroying local variables and exiting the current scope, is known as a

01:44.340 --> 01:45.660
"stack unwinding".

01:48.400 --> 01:54.730
When the program finds a suitable handler for the exception, it will execute the code in that catch

01:54.730 --> 02:00.190
block, and then it will continue. So normally it will go on to the next instruction after the catch block.

02:00.640 --> 02:02.500
So that is a bit like returning from a function.

02:02.830 --> 02:05.800
It will execute the next instruction after the function call.

02:08.310 --> 02:11.280
It is possible for the handler to re-throw the exception.

02:11.460 --> 02:16.830
So that means that this exception becomes "live" again, it becomes active. And then the program needs

02:16.830 --> 02:18.690
to finds another handler for it.

02:23.010 --> 02:25.850
To do that, we use the "throw" key word.

02:26.250 --> 02:31.350
If we just put throw, followed by a semi-colon, that is going to throw the original object again.

02:32.040 --> 02:37.230
If we put throw followed by an object, then it is going to throw a copy of that object.

02:38.730 --> 02:40.500
And this can only happen in a catch block.

02:40.800 --> 02:43.560
So it is going to be regarded as a completely new exception.

02:43.830 --> 02:45.450
And then the stack unwind begins again.

02:47.680 --> 02:49.630
So let's have a look at an example.

02:49.900 --> 02:53.920
We have our vector access, inside to try block, in this function.

02:55.600 --> 02:58.930
We have a handler for the out_of_range exception.

02:59.830 --> 03:05.530
So this is going to produce some output. And then we are going to re-throw this exception.

03:07.210 --> 03:10.660
So the program is now going to look for a handler in the enclosing scope.

03:11.080 --> 03:13.540
But there are no more handlers in this function.

03:14.110 --> 03:19.240
So it is going to return to the caller, and look for a catch block there, and it is going to find this one.

03:20.260 --> 03:26.410
So when we run this program, we expect to see the output from this catch handler, followed by the

03:26.410 --> 03:30.280
output from the catch handler in main() for the generic exception.

03:32.740 --> 03:33.650
And that is what we get.

03:33.760 --> 03:38.770
So there is the output from this handler, and there is the output from the generic exception handler.

03:41.140 --> 03:47.710
If we throw some other type of object, so let's say we have a generic exception, which is based on

03:48.070 --> 03:49.450
this out_of_range exception.

03:50.020 --> 03:51.070
So let's see what happens.

03:55.270 --> 04:00.580
So we have the output from the catch block in func() again, and we have the main() catch block again.

04:00.910 --> 04:08.740
And because we caught by reference in main(), polymorphism works. We get the right virtual member function.

04:08.920 --> 04:15.190
So this will call the version of what for the out_of_range exception, and not the generic version.

04:19.350 --> 04:20.840
So why would this be useful?

04:21.510 --> 04:26.520
One situation is where you have an exception that you want to handle somewhere else, but you want

04:26.520 --> 04:31.830
to log the information about the error condition where it happens, when you still have all the

04:31.830 --> 04:32.520
information.

04:33.720 --> 04:36.480
You could also add extra information to the exception.

04:37.770 --> 04:42.960
And also, you can convert the exception to a higher level type, like we did by converting the out_of_range

04:42.960 --> 04:45.270
exception to a generic exception.

04:49.190 --> 04:56.210
So here is a code fragment, which does that. We have a low level networking exception, with lots of complicated

04:56.300 --> 04:57.350
technical details.

04:58.580 --> 05:03.380
We can log all these details. We have some sort of logging stream, we do not really need to worry

05:03.380 --> 05:08.090
about that here, and then we can write the details to the log file.

05:09.410 --> 05:15.260
We have a member in this class that we can use, to say which server we are trying to connect to.

05:15.380 --> 05:21.590
So we can populate that. And then we can re-throw the exception with all this information, after we have

05:21.590 --> 05:22.580
logged all the data.

05:22.790 --> 05:25.070
Or we could convert it to a higher level exception.

05:26.030 --> 05:27.410
OK, so that is it for this video.

05:27.800 --> 05:30.710
I will see you next time, but until then, keep coding!
