WEBVTT

00:00.120 --> 00:03.870
Hello again! In this video, we are going to look at catch-all handlers.

00:05.010 --> 00:08.550
We can write a handler which can catch any type of exception.

00:08.970 --> 00:12.330
We just put "..." as the exception type.

00:15.050 --> 00:20.070
So we write our catch handler like this, with three dots as the exception type.

00:20.450 --> 00:27.410
By the way, when I put three dots in blue, that just means arbitrary code.

00:27.770 --> 00:30.770
So here we have any code that might throw an exception.

00:31.040 --> 00:32.630
It does not matter what the code is.

00:33.290 --> 00:37.220
When we have three dots in black, that is C++ syntax.

00:37.820 --> 00:43.490
So we use that with catch handlers and also with templates, which we will see later on in the course.

00:45.750 --> 00:51.870
So this code could throw any type of exception, not just any class from the exception hierarchy, but

00:51.870 --> 00:55.020
also built-in types, library classes, classes

00:55.060 --> 00:56.400
you write yourself and so on.

00:56.940 --> 01:02.670
And the reason for that is that C++ had exceptions before it had the standard exception hierarchy.

01:05.430 --> 01:07.400
So let's look at some code.

01:08.040 --> 01:15.270
We have a try block. We have a catch handler which can handle any type of exception, with the three

01:15.270 --> 01:19.260
dots. When we're inside the body of this cash handler -

01:19.560 --> 01:24.630
You will notice there is no actual arguments here, so we do not have any variables, so we do not know anything

01:24.630 --> 01:26.610
about the type of this exception.

01:27.390 --> 01:31.050
So all we can do really is just log it, print out a message.

01:32.680 --> 01:34.990
So let's see what happens if we throw an int.

01:37.750 --> 01:41.320
So there we are, so it works, and it gets caught by this handler.

01:45.240 --> 01:48.030
What about a C-style string?

01:50.800 --> 01:51.820
OK, and...

01:54.590 --> 01:56.240
now, the vector access.

01:56.540 --> 01:57.860
So what is going to happen here?

01:59.530 --> 02:07.660
Well, this is going to throw the out_of_range error again, the program will look for a handler immediately

02:07.660 --> 02:09.050
following this try block.

02:09.470 --> 02:11.140
It will find one which can take anything.

02:11.350 --> 02:13.330
So we expect to see the same message again.

02:16.110 --> 02:17.070
And that is what we get.

02:18.980 --> 02:22.820
If we had a more specific handler.

02:27.610 --> 02:29.990
For the standard exception base class, for example.

02:38.990 --> 02:43.220
Then we would have a variable and we have some information. So we can call the what() member function.

02:48.080 --> 02:53.120
So when the exception is thrown and the program is looking for a handler, this will be the first one

02:53.120 --> 02:58.460
which matches, because out_of_range is a sub-class of the standard exception.

02:59.850 --> 03:01.530
And so we should see - yes, there we are.

03:01.920 --> 03:05.850
We get the usual exception. Vector error.

03:08.380 --> 03:13.480
So is this really useful? I mean, we have all these exception types in the exception hierarchy, so

03:13.480 --> 03:19.180
we do not really need to throw around ints or C-style strings, or even C++ strings.

03:20.020 --> 03:21.910
Well, it is useful as a fallback.

03:22.390 --> 03:24.580
So let's say we have some code that might throw an exception.

03:24.580 --> 03:29.110
We have a handler for network connection errors, and its child classes.

03:29.860 --> 03:32.830
We have one for data error and its child classes.

03:33.850 --> 03:39.430
If neither of these match, then the next one is this one, which will handle anything.

03:39.730 --> 03:43.240
So this will catch any exception, which is not caught by the handlers above it.

03:44.330 --> 03:49.700
So this will catch any exception, which is not caught by the handlers above it, so this is useful

03:49.700 --> 03:52.660
for alerting us that we have missed an exception.

03:52.670 --> 03:54.770
We need to add another catch block in here somewhere.

03:59.100 --> 04:01.570
And you can also do this with your main function.

04:01.590 --> 04:04.050
You can put a catch-all handler in main().

04:04.800 --> 04:09.120
Normally, if you have an exception which is not handled, then the program will terminate.

04:09.450 --> 04:16.470
But the program also terminates because of a memory access error, or some other bug or undefined behaviour.

04:16.890 --> 04:19.320
So you do not really know. With this one,

04:19.740 --> 04:25.200
if there is any exception thrown during the program, which is not handled, then it will be caught by

04:25.200 --> 04:26.070
this catch block.

04:26.400 --> 04:30.510
So we do at least know that there is an underhanded exception, somewhere in the code, and we can start

04:30.510 --> 04:31.290
investigating.

04:34.720 --> 04:37.720
And you can also use the trick with the exception.

04:37.840 --> 04:41.770
So we have the try blocks for network connection error, data error.

04:42.190 --> 04:47.680
If there is something which is in the exception hierarchy, but not covered by those, then we can catch it here

04:47.680 --> 04:48.730
and get some information.

04:49.540 --> 04:55.630
And if by some chance, there is some weird exception, that maybe a third party library throws, then we

04:55.630 --> 04:57.700
will at least know that there is an unhandled exception.

05:01.610 --> 05:05.300
So a catch-all handler is useful for testing your code.

05:05.630 --> 05:11.240
It will help you find situations where you have missed out catch blocks, or overlooked error conditions.

05:12.290 --> 05:14.840
If you are debugging, though, it is actually not helpful.

05:15.350 --> 05:22.040
The best thing to do there is to not handle the error and lets the debugger trap it. Then you can actually

05:22.040 --> 05:27.710
inspect the object in the debugger, and that will give you more useful information than just a vague

05:27.710 --> 05:29.690
message saying there is an unhandled exception.

05:30.380 --> 05:35.960
There is no information about the error condition, there is no type information. And also it does not

05:35.960 --> 05:40.820
capture other events which might cause your program to have a premature exit.

05:41.300 --> 05:44.870
So in Unix, things like signals, or structured

05:44.870 --> 05:46.460
exceptions in Windows.

05:48.200 --> 05:49.820
OK, so that is it for this feature.

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