>> Now, if you're anything like me and I know I am,
the first time that I get into write some code,
sometimes things go wrong.
Now, maybe whatever it is that you're doing works flawlessly,
but in the real world,
things will go sideways,
and sometimes it will be because of mistakes that you made,
things that you have control over,
and sometimes it will be because something has
changed like database has gone down,
a server name has been changed etc.,
where now my application isn't
going to be able to accommodate that on the fly,
and needs to potentially crash.
So let's talk about how we can
deal with those different types of errors.
But before we talk about how to deal with them,
we should probably start defining a couple of different terms.
I want to try and make a very clear distinction
between error handling,
and debugging, because these are two very different things.
Sometimes people will use them to mean something synonymous,
and they're really not.
Error handling is when I
have a problem with my code that's running,
and it's not something that I'm going to be able to
predict when I pushed my code out to production.
The most common example of this would be a permissions issue,
a database changing, a server being down, etc.
Those things that happen in the wild,
those things that happen in the real world,
there's things that I do not have control over.
Contrast that with debugging.
Debugging is when I know that there's a problem with my code.
That it's potentially giving me
a wrong answer, it's potentially crashing,
and I know that there's something that I've done
incorrectly that's causing my code to go sideways.
That's debugging.
So when we get in and we take a look at things like try, except,
finally, which we'll talk about in a minute,
those are not useful tools for handling debugging.
Debugging again, I've got a problem in my code,
I'm trying to fix that problem, that try, except,
finally is where there's something that's happened external to
my application that I couldn't
predict that something might go sideways,
and I want to be able to exit gracefully.
So we want to make sure that there's
a separation between those two.
Now when we're talking about errors,
things that can go wrong inside of our code,
these fall under three different categories,
syntax errors, runtime errors, and logic errors.
Let's start from the top, a syntax error.
With a syntax error,
a code is not going to run at all.
Believe it or not, you have to choose between the errors.
This is the type of error that you want.
This is typically going to be the easiest to
try and track down because of the fact that again,
your code is just going to fail right then and there,
and the error message that you're going to get will typically
point you right to where the problem is.
So if we take a look at our output,
you'll notice that it's actually telling me right here,
let me go ahead and circle that.
It's telling me right there the line of code.
So if we take a look at our little block of code,
and we'll talk a bit more about if statements later on,
what we're actually missing right out here
after that y is a colon.
So that's why it's giving us
a syntax error because we're missing a key there.
Now, one really nice thing about Python is because
of the fact that it's not using curly braces,
you won't have to worry about tracking down a curly brace
when trying to figure out what's wrong with your code.
If you've done something like Java,
or JavaScript, you'll know that can sometimes cause some problems.
So syntax errors are good errors. We want those.
Now, runtime errors are the second best type of error.
Where a code is running,
something has gone wrong,
and it's going to blow up.
Now, in my case here,
the problem that I'm going to run into is that I'm
trying to do that classic divide by zero.
When we hit that line in our code,
it's going to give me that error message that you see right
down there at the bottom, division by zero.
It's also very handily going to point
me at the line number where the problem occurred.
Runtime errors are actually pretty decent errors,
because they will give me a little bit of
information right upfront to
let me know where to start for trying to debug my code.
Now, when you get a runtime error,
the basic strategy here is to
start from the line that it's given you,
and then work your way up to see where the error occurred.
Now, one important tip that I want to give you here.
When you're dealing with a runtime error,
I'm going to guarantee you
the problem is somewhere inside of your code.
One of the most common mistakes that I see
new developers make is they'll go in,
they'll try something, it'll go wrong,
and they'll make the assumption that there's
a problem inside of the framework that they're using,
inside of the runtime that they're using etc.
While it's technically a possibility,
chances are it's not going to be there.
So much so that you probably have better luck of hitting
the lottery than you do in finding an error inside of a framework.
Again, I don't want to say that this doesn't happen,
but it's extremely rare.
I can pretty much guarantee
you that if you're getting a runtime error,
assuming that it's not something like a server being down,
it's an error inside of the code that you've written.
Start there, finish there,
that's where the problem's going to be.
Let's close out our conversation about try,
except, finally with a couple of last little odds and ends.
First up you'll have noticed inside my demo that I
had a try except else, not also works.
Where in that case the else is going to be like
I have up here which is that blank except,
where I'm just not looking for a particular parameter.
Either one will work just fine.
For me, I like that except just because it's
a little bit more consistent
with a lot of other programming languages.
But again, feel free to use whatever it is that you might like.
Now, some final words here.
I know that first bullet point might be a little bit confusing,
but hear me out, try,
except, finally is not used to find bugs.
Let's again identify what a bug is.
Bug is where I have something wrong in my code,
where I know that this code will not
run if it follows this particular path,
or does this particular thing,
and I have control over them.
If it's something where a server might be
down or I'm getting input from a user,
where I don't necessarily always
have control over those types of things,
now try, accept, finally is perfect.
But if I know there's a problem in my code,
that's not where I'm going to put in that try, accept, finally.
It's also worth highlighting the fact that
you don't have to catch all errors.
If you're not going to do anything with it,
if you're not going to log it,
if you're not going to gracefully exit,
then just leave it alone.
I will always remember when I was
working with a framework that another developer had written,
what they had done is they had programmed it such
that if the database threw an error, that it would catch it,
and then give me back some just generic error message,
which made debugging my application impossible.
Because I could never see what the original error message was.
So if you're not going to do anything with it,
just let it go.
You might be thinking, "Well, wait a minute Christopher,
that might crash my application.'
Well, you know what?
Sometimes that's exactly what we want to have happen.
That if our application winds up in
a state where it's just flat and not going to work,
that's okay. Let it crash.
That's exactly what crashes are there for.
That's actually sometimes just fine. All right.
The last type of error that we want to highlight is a logic error.
Our logic error is when our code compiles properly if you will,
there's no syntax errors,
it doesn't give us an error message.
So there's no runtime errors,
it just doesn't give us the response that we're looking for.
So in my case,
what you'll notice is that I've
got a couple little variables here.
Let's go ahead and
make sure that I grab my highlighter. There we go.
I've got my y being two or six,
my x being two or six,
I've got my y being 42.
Then what I'm going to do is I'm going to say, "Hey,
if x is greater than y,
then let's print out is greater than y."
Now I go ahead and I run
my application, and I don't get a response.
If you were listening carefully,
you'll probably have noticed that I actually
said the incorrect code here.
That what my code is actually saying is x less than y. Right here.
That's what I actually wrote inside of my code.
What I had meant to write however is if x is greater than y.
This is without a doubt the most common error,
or most common mistake that I made,
that I will frequently reverse my Boolean.
Little side note here.
I would definitely recommend taking a look
at unit testing and test-driven development.
They're concepts that are beyond the scope of this course,
but what they're about is writing
little automated tests to try and catch mistakes in your code,
and they're really very much designed
to catch these types of mistakes.
I'm a huge fan of unit tests.
Definitely recommend taking a look at unit test inside of Python.
In any event, logic errors
are the types of errors where everything runs,
but we just don't get the right response.
So how do we then start tracking all of that down?
Well, if you do wind up getting something going sideways on you,
and it potentially throws an error message,
take a look at the stack trace.
Stack trace is going to show you
all of the different calls that have been made,
the last calls are at the top,
the most recent ones are down at the bottom.
That's where your code is going to be.
Look for line numbers,
that will give you a perfect place to start.
Now, to try and find your mistake, reread your code,
check the documentation, as always,
search the Internet, Stack Overflow is your friend.
Maybe just take a break.
I can't tell you the number of times where I've
been battling a bug in my code,
and I just simply took a walk.
Or I went home for the day, had dinner, slept,
woke up the next morning,
and then that's where my problem is,
sat down with the computer,
went in, and fixed it.
Sometimes you just simply need to walk away.
The other big thing that sometimes you need,
is just another set of eyes.
So if you work with somebody who does Python,
have them take a look at your code.
Sometimes that fresh viewpoint will be exactly what you
need to try and debug your code.
That is how we can deal with
the different types of areas inside of Python,
and when and how to use that try, except, finally.