hi everyone so the other day I was
working on my web app called edit dojo
and I ran into a really nasty bug it
took me a long time to solve it maybe
like four hours you know overall it was
just a terrible experience just
debugging it but I decided to take this
opportunity to you know talk about
debugging in this video so I'm gonna
first walk you through how I solved this
particular bug exactly and then along
the way I'm also gonna give you some
general tips on debugging so you'll be
able to use these tips on any
programming language even though I'm
gonna be using Python in this particular
video okay so here's the website I'm
making right now I'm running this
website locally you can tell that just
by looking at the url bar this is the IP
address that represents my local server
now when you scroll down on this landing
page and when you click this button that
says sign up signing with Twitter you
can sign up or sign in with Twitter go
to Twitter and then back to my website
so that's the expected behavior but the
problem was when I put this website on
Heroku which is a website that helps you
host your own website in the cloud
I started getting a bug okay so let me
just quickly show you what the bug was
exactly let me go to the version of my
website that's hosted on Heroku right
here and when I clicked the same button
sign up sign in with Twitter I got this
error social network login failure and
the funny thing was I was running
exactly the same code for my local
server as well as on Heroku so what's
happening here okay so the first thing I
thought when I got this error is that
the obvious difference between these two
situations is the URLs so I thought
maybe I set up something incorrectly on
Twitter's developer website in regards
to the URLs and that actually brings me
to the first step I wanted to talk about
for debugging in general and that is to
come up with a hypothesis and test it
and come up with another hypothesis test
that
so you need to you know really think
like a scientist when you're debugging
and like I said the initial hypothesis I
had for this particular bug was that
maybe I setup something incorrectly on
Twitter's developer website so I checked
it and I checked you know this section
in particular callback URL I checked if
it's HTTPS or HTTP for example I tried
both but none of those things worked so
at that point I wanted to come up with
another hypothesis but I was sort of out
of ideas so I decided to first look into
the code to try to see you know the
cause of the bug but before doing that I
wanted to you know reproduce the bug
locally or at least reproduce something
similar to the bottom Oakley and that's
actually my second tip for debugging
I think we're producing the bug locally
is important because you know trying to
find the cause of a bug usually takes a
lot of trials and errors you need to you
know sometimes play around with the code
too and if you do it with the server it
might take a lot of time just
communicating with the server so ideally
when it's possible and when it's
convenient you should try to reproduce
the same bug or a similar bug locally
and then analyze it there first and in
this particular case I just went back to
Twitter's developer website and then I
actually deleted one of the callback
URLs you know the one for the local
server and when I did that and when I
tried the same thing again on the local
server I actually got the same error so
this is not necessarily the same bug but
I thought you know once I analyzed this
particular error I'll be able to use you
know the inside I can get from that
analysis to find the cause of the
original bug so that's exactly what I
did and to analyze the error that I just
created on my local server more
carefully I started reading into the
source code and that's actually my third
tip to read the source code carefully
and then play around with it and this
process was actually not that simple for
me because I was using this pretty big
open source library called Jango all off
you know you don't always have to read
the source code
of every single library you are using
but I think it's pretty common to have
to be able to read other people's code
for example if you end up working with
other developers at work anyway I
started looking through this codebase
some more and I found this directory
that says Twitter so I thought you know
this must be at the relevant directory
here because we're using Twitter logins
and you know for example I found
viewstub pi file here in the twitter
directory and i thought it was relevant
so what i did was i copied this file and
then pasted a locally to override some
of the functions in this file and i
actually did the same thing for another
file and i called it all these depay
because this was built up pi within the
awestruck tree and then you know looking
through these two files I thought okay
this view function right here in our
fuse must be the view that's called when
this URL is opened by the user that was
sort of my hypothesis and to test that I
decided to you know put some print
statements here and that's actually my
fourth tip for debugging to be able to
use print statements effectively so let
me show you how I usually go about using
print statements for debugging here I'm
just gonna write print YK one you know
YK is my name and the reason that I put
my name in my print statements what I'm
debugging is so that they're very
distinct you know sometimes there are a
lot of things being printed into the log
and this way it's going to be much
easier to find my print statements and
then the reason I put a number after my
name is so that you know we can do
things like print YK one here and then
print YK 2 here and this way if we see
both of them we'll know that you know
both of these parts are being executed
but if we only see YK one in the log
we'll know that you know only this part
is being executed but not this part so
here just as an example we can you know
spam this whole function with print
statements um
so YK three here and then YK four here
and let's see what happens let me just
refresh this page when I go to terminal
I see all of these YK one two three and
four so from that we can tell that you
know all of these parts of this function
are being executed and then it goes to
self dot dispatch
so let's look into this function okay so
I looked into that function and then I
kept repeating the same pattern
basically analyze the code by using a
bunch of print statements and then try
to understand what's the next function
that I should look at and then
eventually I got to this function called
get request token so I kept doing
basically the same thing as what I did
earlier for this function
you know I added a few more print
statements and then I decided to focus
on this particular variable called a
response because it looks like a
response that we get from Twitter and
when we try to do Twitter login and so
I'm printing the response variable here
after the string response so let's see
what that looks like it's just this one
we have response and then the response
variable is response for three that's
actually not that helpful so we need to
examine it you know a little bit more
carefully and that actually brings me to
my fifth tip for debugging and that is
to use a debugger effectively so just in
case you don't know what a debugger is
it's a way to run this code and then
stop it wherever you want and examine
the code more carefully so here I can do
import PDB Python debugger and then PDB
dot set trace and this way we should be
able to when we refresh that page that
we saw earlier we should be able to stop
it right here so in terminal when you
are in the debugger you should see
something like this PDP PDB and then
there are a lot of different commands
here but the only command that matters
here is P which you can use to print
anything you want to print so if you do
P response you should be able to print
that
and if you do a response that dict that
Keys you'll be able to see you know what
variables this object has and there's a
bunch of stuff here but actually the
only one that's important is content and
if you do response that content actually
responds that content this is what you
see
I get callback URL not approved for this
client application which actually makes
sense because you know I got rid of the
URL for the local application so you
might say you know what's the point of
doing all of this well the point is that
you know I'm gonna go back to the
original code and then here what we can
do is we can print not just response but
also response dot content I think so
this way we'll be able to print more
information about the error that we are
getting and we'll be able to do the same
thing for our server in the cloud too
so after that I committed all of these
changes on git and then I pushed those
changes to Heroku so we can test it
there and then you know on the Heroku
version of the website I made sure you
know I'm still getting the same error
and I checked the logs with this command
and here this is what we're getting a
response content is you know bunch of
stuff here and then the message is could
not authenticate you so it's obviously
different from the error that we saw
earlier and so I started thinking you
know what could be the cause of this
could not authenticate you well you know
one common reason of not being able to
authenticate is that the passwords are
wrong right and it turned out when I was
copying my Twitter Keys Twitter API keys
from local to Heroku using this thing
called environment variables I missed
one letter from from one of my passwords
and that's actually why I was getting
this bug and that's why I ended up
spending four hours just debugging it
and you might say you know you could
have checked it like in the first place
when you got the bug but
sometimes you just don't think of it and
you know you end up wasting time anyway
that's it for this video hopefully you
learned something new today and if you
have any other you know debugging tips
feel free to share them in the comment
section because you know other people
might be able to learn from them
and I'm gonna put the code I showed you
today at this URL as usual and thank you
as always for watching my videos I'll
see you guys in the next one