Struggling with Python errors? Learn how to handle exceptions like an expert with this in-depth guide on Python exception handling! Whether you're a beginner or an advanced programmer, this tutorial covers everything from try-except blocks to multiple exceptions—making your code robust and error-free.
🚀 What You’ll Learn: ✔ Python exception handling fundamentals (try-except, finally, else) ✔ How to handle multiple exceptions efficiently ✔ Best practices for error handling in Python ✔ Differences between Python exceptions vs. exception handling in Java/Spring Boot ✔ Advanced exception handling techniques for cleaner code
📌 Perfect For:
Python for beginners learning Python basics
Developers transitioning from Java/Spring Boot exception handling
Coders looking to learn Python programming the right way
💡 Level up your Python skills—watch now and write bulletproof code!
Hi, welcome to my course on exceptions
in Python programming language. In this
course, I will cover the topic of
exceptions in its
entirety. Before we get into practical
examples in regards to exceptions,
here's a general information you should
know about exceptions in Python
programming language. When an error
occurs in our code, the program will
stop automatically. data will be created
called an exception. These activities
are often referred to as raising an
exception. When Python has no idea what
to do with your code, it raises an
exception. If we do not take care of the
raise exception, the program will be
terminated and you will see an error
message displayed in your console by
Python. If we handle the exception, the
program can be resumed and its execution
will continue. Python offers effective
tools that allow us to observe
exceptions, identify them and later
handle them. Each potential exception
can be identified by its name so we can
easily categorize and react
accordingly. Here we have a practical
example of an exception being
raised. So we have the following code a
variable called data to which we will
assign an integer of one. Then in the
second line we will use the same
variable called data and we will try to
divide the data variable which contains
an integer of one by integer zero. As a
result we will have the following error
displayed in our console. trace back
most recent call last file this is the
name of our Python file div py line two
which refers to the second line of our
code data here the division plus the sim
operator so shortcut operator has been
used to divide the following variable by
zero however it's not possible to divide
an integer one by integer zero therefore
we will have an exception called zero
division error raised by Python
programming language. Now the zero
division error is one of the most common
exceptions in Python programming
language and is usually being raised
when a division is performed when we try
to divide an integer of one by integer
of zero. Then moving forward here we
have another exception is also well
known and is very popular among
exceptions. It's called index zero. So
here we have the following line of code
list to which we will assign a list
variable. We have assigned an empty list
data type to our list variable. Then we
use the X variable assignment operator
and we will try to access our list
variable at index zero. Therefore, we
will have also an error displayed in our
console trace back more recent called
file the name of the file line two which
refers to this specific second line of
our code. List indexing index error list
index out of range. So when there is a
error in regards to indexing in our
code, we should we should expect index
error to be raised in Python programming
language. When you run an incorrect
code, you will get error displayed on
your screen. For example, if you try to
add an integer value to a string value,
you will get an error message displayed
on your screen. Such as for example,
concatenation is not possible with a
string value to add to an integer value.
For that not to happen, for the code not
to be terminated, there's a try and
accept block ready to handle such
exception. And for every type of error,
there's a specific exception ready to
handle it. So below we have an example
of try and accept block which consists
of both our
keywords. And for example inside the try
block we will place a a variable of a
which now stores a string of seven and
we'll try to add an integer to a string
of seven and we will print the following
result. Now the following code is of
course an error. So it will auto
automatically go to the
accept block and instead of having an
error displayed on our screen such as
concatenation is not possible etc. we
will handle it and we will have cannot
add a string to an integer text
displayed on our screen. So again we
have try and accept block. With a try
and accept block we are able to handle
an exception. We can use multiple except
blocks in our code if we wish to handle
more than one exception and are
anticipating our code to raise an
exception different to the one the first
except block was placed to handle. As
the practical example here suggests
inside our try block, we'll place the
following line of code. With the help of
the input function, we will ask the user
to enter a number. The data will be
assigned and stored in a variable called
n.
Then we will try to divide the data
stored in a n variable by integer one
and store the result of a division in a
variable called y. And finally the print
function should display the data stored
in y variable. We will use the first
accept block to handle an exception
related to zero division error and we
will have the print function display the
following message in our console. You
cannot divide by zero.
Sorry. The second except block will
handle type error related exception and
the print function will display type
error has occurred in our console. As we
run the following code, the zero
division error exception won't be able
to handle the exception raised in our
try block as the data received by the
input function is transformed into a
string data type. Therefore, a division
will not occur. So, the type exception
is there to handle such exception. As a
result, we will have type error has
occurred displayed in our console. Also,
if you press Ctrl C while the program is
waiting for the user's input,
specifically when the input function
occurs and we press Ctrl C while the
program is running, an exception named
keyboard interrupt exception error will
appear in your console. There are 63
built-in exceptions that exist in Python
programming language. It's a treeshaped
hierarchy.
There are two categories of exceptions.
Concrete exceptions and general
exceptions. Exception located closer to
the root can be considered more
general. General exception can easily
handle an exception raised as long as it
matches the coverage and a concrete
exception is not required. To
demonstrate that we will use the
following practical example and showcase
the results within our function. We will
try to perform division. We will utilize
the try except block to invoke the
function and have the arithmetic error
exception handle any possible exception
relating to zero division.
When we run the following code, we will
invoke the function inside the try block
by placing an integer of zero inside the
parenthesis. As a result, a zero
division error will be raised. However,
as I've stated initially, a general
exception of arithmetic error, which is
a general exception, will easily handle
such an exception as it fits its
designation. So we will have exception
was raised displayed in our console with
the help of the print function. The
raise instruction raises a specified
exception as if it was raised in a
normal natural way. So here we have an
example of us creating a function called
division empty parenthesis then column
then inside our function using the raise
keyword to raise the zero division
error. So by using the raise keyword, we
will raise the zero division error
ourselves. So instead of letting Python
to determine whether to raise an error
after reviewing a specified code, we
will raise the zero division error
ourselves explicitly by using the raise
keyword. Then we will use the try Excel
block. So inside the try statement, we
will invoke our division function.
By invoking our division function, the
zero division error will be raised
thanks to the raise keyword. Then we
have the accept statement. Next to our
accept statement, we'll place the
arithmetic error. So arithmetic error
should be able to handle the zero
division error. As a result, the print
function will display error in our
console. Now if you are unable to handle
the
specified zero division error of course
Python will terminate the code in a
natural way. So this is how the raise
keyword can be used with exceptions in
Python programming language. The raise
instruction may also be utilized in the
following way. Inside our code here we
have an empty raise
instruction. An absence of an exception
name. It is possible to use the raise
instruction in the following way.
However, it has to be placed in
exception branch only. If we are to put
it anywhere else, we should expect an
error to be displayed in our console.
One more important note, we can
distribute the exception handling among
different parts of the code. So inside
our function we have the tri accept
block and outside of function we can
also have a tri accept
block. Now we have the following
function here def division inside the
parenthesis we have the n parameter.
Then we have the tri accept statement.
Inside the try statement we have the
return keyword and divid divided by
zero. and parameter will be divided by
zero. In case an error occurs, we have
the accept block here. Print function.
Inside the print function, we have the
error string data type as an argument.
And here we have the empty raise
instruction. Then outside our function,
we have the try statement again. Try
except statement. Then inside our try
statement, we have we will invoke our
function called division by placing
integer one as an argument. In case in
our course, we have the except here
except except arithmetic error. So we
should expect the arithmetic error to
handle this specific exception. Then we
have the print function. Inside print
function we have the not case string de
type as an argument. So first we'll
invoke our function called division by
placing an integer of one as an
argument. If we go to our function the
try statement will try to divide the n
parameter which contains zero uh sorry
integer of one by integer of zero. Of
course an error occurs error will be
raised. Except lock should be able to
handle it. So we will have error
displayed in our console.
Then we'll use the raise empty
instruction. The raise instruction since
uh zero division error has been raised
as we have tried to divide one by zero.
The raise empty instruction will raise
the zero division one more time. Then
here outside our function the accept
block should be able to handle it by the
arithmetic error. Therefore we will have
not okay displayed in our console. So
this is how we can use the empty arrays
instruction and also distribute the
exception handling among different parts
of our code. By placing the triet block
inside our function as well the tri set
block outside our function in case an
error occurs inside our function. We can
handle it by triet block which has been
placed outside. Now we will use an
instruction called
assert. So we have the following line of
code. First we will import a module
called
meth. Then we have data equal to float
function. The input function the inside
the parenthesis a string data type of
enter a number. So we will ask the user
to enter a number. Then the receive data
will be transformed to float data type
by using the float function and the
result of the following line of code
will be placed inside our variable
called data. Then we will use the assert
instruction. So we have assert data the
greater than or equal to operator and
the flow data type of
2.0. So you can think of the assert
instruction as a conditional statement.
We use the assert instruction to be
absolutely safe from the wrong data and
when you are not specifically sure that
the data has been carefully examined by
a
programmer. and assertion itself is
there to assist an
exception. So how can we use the assert
expression? So when we run this specific
code
here and enter a number will appear in
our console. If we are to type an
integer of four, the float function will
transform the integer value into a float
data type. Then it will move to this
line of
code. Then the assert instruction will
make sure that the following data
variable which now contains a flow data
type
4.0 is greater than 2.0 or equals to a
flow data type
2.0. If the assert instruction is
correct, it will move to this line of
code. So we will get a square root of
four. As a result, we will have
2.0 displayed in our console. Now, if
you were to place when the enter number
appear in our console an integer of one
for example and the flow data type float
function will transform it to a flow
data type 1.0. Of course, it's not
greater or equal to a flow data type of
2.0.
As a result, we will have assertion
error displayed in our
console. So again the assertion error
the assertion instruction sorry can be
used as a conditional statement inside
our code. And again when we are not
absolutely sure that the data has been
carefully examined by a programmer for
example if you are to receive a specific
code we can place the assert instruction
inside that code to make sure there is
no errors in any of the line of the
code. There is another branch which we
can place alongside the try accept
block. It's the else statement. The else
branch will only be executed in case of
a code successfully passing through the
try block. The else branch has to be
placed after the except block. Please
remember that. Now through the practical
example, I will demonstrate the workings
of the else branch. When we invoke the
access function by placing the following
line of code, the val parameter will
receive integer zero. We will go to the
try block, create a list data type
containing three elements and assign it
to a variable called element. Then we
will use indexing to access an element
at index zero. As a result, our code
will reach the else branch and we will
have success appear in our console as
well as integer zero with the help of
the return keyword.
We will invoke the function one more
time by assigning integer five to the
val parameter. This time we will again
reach the try block create a list data
type and we'll try to access an element
at the index five. As a result an
exception will be
raised specifically index error. Our
code will move to the accept block where
we will have index error appear in our
console as well as integer five as we
have used the print function and the
return keyword. Our code will stop here.
It will now reach the else branch. So
this is how the else statement can be
integrated with our tri set block and
the else statement can be referred to as
a else branch. We can extend our triac
block by adding another branch called
finally. Finally block must always be
the last branch of the triacet block. We
don't have to place both else and
finally branch within our triet block.
It can be either one of them or both.
And most importantly, the finally block
is always executed regardless of the
result. Now let me try to demonstrate
the capabilities of the finally block
through this practical example. As you
can see our access function contains the
try accept block as well as the else and
finally block. When we first invoke the
function inside the try block a list
data type will be created as well as
indexing will be performed successfully.
Therefore we will reach the else branch
as well as the finally block. So we will
have success and integer zero displayed
in our console through the else branch
and always executed message will appear
in our console thanks to the finally
block. Now we will invoke our access
function by writing the following line
of code. As a result, after the creation
of a list data type inside the try
block, an exception will be raised,
specifically an index error due to out
of range indexing as integer 5 was
assigned to valid parameter. So our code
will move to the Excel block where we
will handle the exception and we'll have
index error appear in our console as
well as integer 5. Our code will skip
the else branch. it will reach the
finally block which will display always
executed in our console. So as you can
see the finally block is always executed
regardless. Exceptions are actual
classes. When an exception is raised an
object of the class is instantiated. So
an object is being created and the code
goes through all levels of program
execution looking and searching for the
adequate except branch that is prepared
to deal with a specific exception.
Exception as an object carries useful
information and in order for us to
access an exception object we have to
catch the object using the as keyword.
Then give the object an identifier such
as analias. I will use this practical
example to show how it works. A list
data type will be created inside the try
block as well as incorrect indexing will
be used to raise an exception.
Therefore, we will move to the except
block where we will handle the raised
exception and capture it by using the s
keyword as an object. As you can see, we
have given an allias of index to our
captured exception object. When we reach
the print function and place the
index inside the parenthesis of the
print function as an argument, a message
of list index out of range will appear
in our console, which is of course the
reason behind the
exception. The second print function
will also display the same message in
our console. We have used the SDR
method. By applying the SDR method on
our exception object, we should receive
a message in human readable form
describing the cause behind the
exception. So again, this is how we can
capture an exception as an object using
the S keyword. And of course, an
important note, every exception is a
class.
The base exception class has a property
called arcs. Arcs property is a tupole.
It gathers all arguments passed to the
class constructor. It is empty of course
if you do not pass any arguments to the
constructor. In the following practical
example, we will create a function
called display and equip it with few
lines of code. Then we will utilize the
try accept block to demonstrate the
functionalities of the arcs property.
Inside the try block, we will raise an
exception and pass an argument to the
exception class constructor, a string
data type of im. As we move to the
accept block, we will handle the raised
exception and capture it as an object by
giving it an allias of ex.
As we have used the exception class in
our case, as the exception class is a
subclass of the base exception class, it
will also inherit the arcs property. So
the exception class does also contain
the arcs property. Using the print
function, we will print the object
itself first. Then we will apply the str
method to the object. We will use the se
keyword to separate two objects with
colon. As a result, we will get IM
displayed in our console separated by a
colon. We will also use the end keyword
to end it with a colon. Finally, we will
invoke the display function by placing
the following line of code
exarch. As a result, values collected by
the arcs property will be assigned to
the element parameter. First we will
check the length of the parameter by
using the length function and assign the
value to the length variable. With the
help of the if statement we will check
if length equals to zero as it does not
we will not print zero in our console
but move to the else statement which
will display a tuple data type of I am
in our console. In this lecture, we are
going to build our own exception from
scratch. If we want to create our own
exception, we can inherit from a
specialized exception. However, it will
be closely connected to Python builtin
exception tree. If you want to inherit
from our own hierarchy and don't want it
to be closely associated with Python
exception tree, we need to derive it
from exception classes like general
exception. So we will use the general
exception as the base class as our own
exception will be derived from here. Our
exception will be equipped with specific
information. Our first exception class
will be called warning
ex will inherit from a general
exception. Constructor will contain two
predefined parameters along with a self
parameter. We will access the exception
class constructor and update it with the
announcement parameter. Our class will
also contain an instance variable called
name to which a name parameter be
assigned to. So we have just created our
own exception. We will create one more
exception called error exec. However,
this time warning exception will serve
as its superass. constructor will
contain three parameters as well as the
self parameter. We will also access our
superasses constructor in order to
override and update its values. An
instance variable called date will be a
part of our exception to which the date
parameter will be assigned to. We will
create a function called call a with a
name
parameter. We will use two if
statements. The first if statement will
ask if name parameter equals to string
data type of warning ex we should raise
warning exception as well as pass two
arguments. As you are well aware of the
fact when the raised instruction is
placed next to the exception class a
class is instantiated an object is
created. Therefore the arguments will be
passed to the name and denouncement
parameters of the warning ex class.
We'll do the same when the name
parameter equals to error
exec. Create an object and the arguments
to the constructor of the exc class. We
will use the for loop to loop through a
list data type containing two string
elements and use the try accept block to
invoke the function as well as handle an
exception. As we run the following code,
the temporary x variable will be
assigned the warning ex string data
type. We will invoke the call a function
inside our try statement by placing x as
an argument. As a result, the name
parameter of our call a function will
receive a value of warning ex string.
The if statement will check if name
parameter equals to warning ex. Since it
does, we will raise the warning
exception. Our accept block of warning
ex should handle it which we have
captured as an object and given it
analyze of we. When we use the print
function to print the object itself, we
will have this is warning with
exclamation points appear in our
console. Then we will have a colon
appear in our console on the same line.
And finally we will access the name
instance variable of our exception. So
we will have warning ex appear as well.
We will loop one more time. This time
the x variable will receive a string
data type of error exec. We will invoke
the call a function inside our try
statement. Name parameter will be
assigned error exe string. We will move
to the second if statement as the name
parameter does not equal to the warning
ex string data type in the first if
statement. We will raise the exception
of the error exec as the name parameter
does indeed equal to error exe string
data type. We will handle the raised
exception with the accept block of error
exec which we have captured as an object
and given analyze of ex. The print
function will display three arguments.
First we will have triple error appear
in our console then a colon and finally
as we have access the date instance
variable of our exception class we will
have integer of 2024 appear in our
console as well. In this lecture we will
cover more advanced concepts of
exceptions. We can get additional
information regarding an exception
object by using attributes such as name
and path. I will use the following
practical example to showcase their
functionalities. Inside our tri block,
we will use the import keyword to import
a specific module called file. As such
module does not exist, we will use the
accept block to handle the raised
exception with import error exception
which will be captured as an object and
given analyze of
IE. We will first apply the name
attribute to our exception object and
place it as an argument inside the print
function. As a result, we will have file
displayed in our console. The name
attribute displays the name of the
module which we have attempted to
import. We will use the print function
again, but this time apply the path
attribute to our exception object and
place it as an argument. As a result, we
will have none appear in our console as
a result. The path attribute displays
the path to the file which caused the
exception. We can also get none as a
result which was the case
here. There are more attributes that are
available and can be used on exception
object. However, certain attributes can
only be applied on a specific exception
object. Here's a list of attributes we
can use on a uniqu error exception
object. Uni-ord error exception is a
subclass of the value error exception.
Therefore, all the listed attributes are
accessible to the value error exception
as well. The unic code error exception
is raised when unicode related encoding
or decoding error occurs. So first we
will try to decode the string code point
inside the try block using the decode
method which will raise an exception. We
will handle the raise exception with a
unic code error exception inside the
except lock and capture it as an object
and give it an ally of
UE. First attribute applied on the
exception object will be the encoding
attribute. As a result, the print
function will display UTF8 in our
console. The encoding attribute displays
the name of the encoding that raised the
error which in our case was the UTF8
which we have indicated in the decode
method. The next attribute we will use
is called reason. The reason attribute
will simply describe the reason behind
the error in a string format. So as a
result the print function will display
invalid start byte message in our
console. When object attribute is
applied on our exception object, we will
have the following message displayed in
our console as the object attribute
displays the name of the object the
codec was attempting to encode or decode
in our case. And finally we will use two
more attributes called start and end and
use the print function to display the
result. So by using the start attribute
we will have integer zero appear in our
console and by using the end attribute
we will have integer one appear in our
console. The start attribute displays
the first index of the invalid data in
the object while the end attribute
indicates the index of the last invalid
data of the
object. In this lecture we will discuss
an interesting concept called chained
exceptions. The exception chaining
feature is utilized to effectively deal
with an additional exception that we
have indirectly or directly raised while
dealing with another exception.
When an additional exception is
indirectly raised while dealing with the
first one, it is an example of implicit
chaining. When we are to knowingly raise
another exception while handling the
first one, such case is referred to as
explicit chaining. In both cases of
implicit and explicit chaining, an
information about the previous exception
will not be lost. We are introduced to
two attributes with chaining concept. We
have the context attribute which is
inherent for implicitly chained
exceptions while another attribute
called cause which is an attribute for
explicitly chained
exceptions. By using these two
attributes, we are able to keep a
reference to the original exception
object for later use.
We will use the following practical
example to implicitly cause an
exception. As we run the following code,
an interesting message should appear in
our console such as during handling of
the above exception, another exception
occurred. So as you can see at the code
here while trying to handle the indexing
error exception with the general
exception itself inside the except block
we have placed the print function and
inside the parenthesis we have placed
integer one divided by zero. As a result
we have caused another exception. So
again this is an example of chained
exception. While dealing with the first
exception in our case the index error we
have raised another exception zero
division error. So a chain exception has
occurred in this code. Through this
practical example you will see and
understand the workings of the context
attribute. First an exception will be
raised due to the incorrect indexing. We
will use general exception to handle the
error and capture it as an object. We
will place a triacel block inside our
accept block to print another data and
handle any potential exception. We will
cause a zero division error by trying to
divide integer one by integer zero. Use
the zero division error exception to
handle the exception itself and capture
it as an object. First, we'll print the
outer exception object. So we will have
list index out of range message appear
in our console. Then we'll print the
inner exception object. So we will get
division by zero message in our console.
Now we will apply the context attribute
on our inner exception object. As a
result with the help of the print
function we will get a message of list
index out of range in our console. So as
you can see the information about the
original exception was not lost and is
referenced by the context attribute. Now
we will concentrate on the cause
attribute. We'll create our own
exception first. We'll use the try block
to access a specific element at index 2
which of course will raise an error.
We'll use the index error exception to
handle the error and capture it as an
object. Now we will intentionally cause
an exception by writing the following
line of code. We will place the entire
code inside the function called check.
So we will use the track acet block to
invoke the function and handle the
potential error. So when we run the code
and invoke the function, we will handle
the exception with our personal
exception and capture it as an object.
Then we will use the print function and
utilize
formatting. So as a result we will have
exception new error was raised due to
list index out of range. So we have
applied the cause attribute on our
exception object. So we have received
list index out of range message in our
console along with exception new error
as we have first captured the object and
label it
ne. So if we fail to handle the
subsequent exception which we have
explicitly raised, we will have a
message appear in our console of the
above exception was the direct cause of
the following exception. Message appear
in our console as by writing the
following line of code we have tried to
raise an exception explicitly from
original exception object. The final
attribute I would like to talk about
that is closely associated with
exceptions is called trace back. Unlike
the other attributes, each and every
exception object owns a trace back
attribute. So we can apply it to every
object. I will update the previous code
by incorporating the trace back
attribute. Using the trace back
attribute, we are able to trace an error
as well as the functions.
the function calls made in our code. And
in the following lecture, I will also
use the traceback module to get a more
detailed explanation of some of the
errors that were raised in our code at
some point. First, we'll create our own
exception. Then create a twoelement data
type list data type. Use try except lock
inside our function to raise original
index error exception. And while trying
to handle the raised exception, we will
explicitly raise another exception by
placing the following line of code. So
when we invoke the function by using the
try block inside the
function, index error will be raised and
handled by the index error
exception in the except block and of
course capture it as an object. However,
we will raise additional exception by
writing the following line of
code. Outside the function, we will use
the accept block and handle it with our
own exception which will be captured as
an object as well. First, we will apply
the trace back attribute. As a result,
we will get the following message appear
in our console which is the number of
the memory point where our trace back
object is located at.
We will use the tie function and apply
it on our exception along with a trace
back
attribute. As a result, we will get
class trace back message in our
console. In this lecture, I will use a
module called traceback and use its
method called
format_TB to get more details about the
exception that will occur in our code.
We will update the previous code by
first importing the traceback module. We
will use a method called
format_TB which will get us a list of
strings describing at what point our
code broke down and raised an
exception. Since the method returns a
list, we will assign it to a variable
and use a join method to combine a new
line character with a variable data. So
instead of the entire data being on one
line, each string will appear in a new
line. So when we run the following code,
we will get the following message appear
in our console. The first line is due to
us applying the trace back attribute on
the object. The second result appears as
we have used the type function. And
finally we got the following lines
displayed in our console as we have used
the
format_TB method. It states that at line
15 an exception was raised when we have
tried to invoke our check
function. And another error was raised
at line 10th when we have
explicitly tried to raise an exception
from index error exception object.
And we will print check is complete in
our console as well. As you can see, we
have manage to smoothly run our code
without our code being terminated.