Welcome back.
In this video I have something really cool for you.
And that is the call stack and how exceptions work in the call stack.
So I have a little example here of code that is prepared already.
And we have a few methods.
So we have the static void level one method which calls level two.
Now obviously there could be a lot more code here.
It could be like 15, 50, 100 lines of code.
And in the end, in this case, it's obviously useless to just have a method that calls another method.
But usually you would have a lot more code in it.
So now this is just for illustration here.
Now this level one method calls the level two method.
And inside of the level two method we would also have a bunch of code, a lot of code that just gets
executed, and so forth.
But then I'm throwing an exception inside of level two.
Now in this case I'm actively throwing it myself so that somebody can manage it.
So who is this somebody?
So either this somebody is the developer.
So the error just occurs.
My application crashes and I know okay, there's an error that I need to manage better.
Or I have somebody up the stack that handles the error.
So what does up the stack mean and how could it be handled.
Well we saw earlier when we say throw then an error will just occur.
Our application will crash.
But that was not entirely correct because in our new case that we have here, what we do is we try to
execute level one, which is this method, which then in turn calls level two, which then throws the
error.
So we're trying to run something that actually causes an error.
But then we're catching an error with an exception.
We're just saying something onto the console.
Like in this case where we say Console.WriteLine exception called in main.
And then it just gives us the message okay.
So let's run this and see what's going to happen.
And you see I get this error which says exception caught in main.
Something went wrong but my application is still working.
I can show you.
So app is still running.
And then let's call this one here CW app running before the try block.
Okay let's run it again and we'll see app running before the try block.
And then exception calls in main.
Something went wrong and then it says app is still running.
So what we can see is that the error handling happens up the stack.
So what we did is we bubbled our problem up the stack.
So in that case we bubbled it from level two up to level one.
And then level one bubbled it to the main method in which we had this try block that then manages the
exception okay.
This thrown exception.
So in our very simple case that we have here we see all the code right.
And we have control over the code.
And we can edit all the code.
But in a big project that you are building with many people, like in a company with dozens of developers
or even just with two developers, not everyone has access to all code or not.
Everyone is responsible for all code.
But what you can do is you can just say, hey, at this moment in the code, I want an error to occur
because something went wrong.
Something isn't right.
And if we just keep going with the next steps, we are going to screw over our database or we're going
to break something.
I throw the error and now please go ahead and manage the error or the exception.
Catch the exception, manage it somebody else or don't.
If you don't, then the app will crash.
But if you do, great, then the app won't crash.
But the managing of the exception, the handling of the exception happens at another layer at another
higher level of the stack.
Okay, so how does that work?
Well, when we're throwing an exception, the code within a method throws the exception, and the runtime
then starts to search for a method that can handle the exception.
In this case we saw it.
The main method can handle the exception because that's what the try block was, right?
Looking up the call stack from the point where the exception was thrown, which is in our level here.
So if our error occurs let's say let's actually run this a little more here.
So I'm adding a line here so that we understand a little better.
You can see it's already grayed out because it says hey this line will never be executed.
Don't even bother.
But I could say something like level two after throw.
Okay, so let me show you that level two is going to be executed before throw and after throw.
So let me run this and we can see app running before try block level two before throw then.
The exception is called an app is still running.
So you see, this throw didn't crash our application, but it prematurely left its method.
So the level two method, it just said, hey, you know what level two method you are not capable of
managing or handling my exception.
So please give it to your higher ups.
Give it to your level one.
Level one says you know what, not my problem.
I'm going to give it to the boss.
Main method.
Main method says all right, you know what level one I'm going to manage your error even though it's
the error of level two.
But yeah that's how the whole bubbling thing works.
So it's really searching for a handler.
So somebody who's trying to handle or who can handle the error and then it's handling the exception.
And if it can't handle the exception.
So if this catch block doesn't have the right exception in it, in our case we have a default exception
which will catch all exceptions.
But if it was like let's say an argument exception, but we are throwing something else like a divide
by zero exception for example.
So in that case it would not work potentially.
Okay.
So this is just an example as to how the call stack works in the sense of one method calls another method
calls another method.
And this is not uncommon right.
This happens a lot whenever we are using a method.
We see that any given method that we are calling is called from the main method, which is already starting
to build up the stack.
So if the method that we're calling in the main method is calling another method, then our stack is
increased by one more and so forth.
Good.
So this was just a little bit of an example.
I hope you enjoyed it.
This was to show you how the stack works, how you can bubble up your error or your exception to a level
where it can be handled or it won't be handled, and then the app will crash.
Cool.
So that's it for this video, by the way.
Let's just quickly prove it okay.
So let's say I will only accept divide by zero exception or manage divide by zero exceptions.
So if I run this application now it will crash.
So it says app running before the try block level two before throw.
And then it doesn't do anything after that.
So it just gives us this system exception.
Something went wrong.
So this also shows you that you can.
And let me make this a default exception.
Again the parent knows how to handle the children, but the children don't know how to handle the parent
interestingly enough.
Right.
So exception is the parent and divide by zero is the child.
Right.
So if I try as divide by zero try to manage the parent exception exception it doesn't work.
But if I try to do a format exception here for example that will work okay.
So it will still not crash my application.
So it's still called the app.
The exception in main good.
So that was a lot of poor information.
Don't worry about it.
We're going to get a significantly better feeling for inheritance later on.
And we're going to see a lot more error situations, which we will catch trying and catching and finalizing,
especially when we come to the database chapters slash the user interface chapters because whenever
you're working with a user interface, something can go wrong because the user can do whatever.
So see you in the next video.