Wednesday, May 24, 2017

Posted by beni in , , , , , , , , , , | May 24, 2017

A few things on Pythons Error Handling syntax and their usages


As a noob in programming, I encountered code error very often. In fact, I am so used to it that I truly expect some error in every snippet of my code. When I dont encounter on, I feel genuinely insecure about it...

However, with the more experience I have now, I meet fewer errors in my scripts, and when I started building web application that requires user input, I need to worry more about mistake made by the user instead of myself.

That was the moment that I realize the power of Pythons error handling - yep, back when I was just learning Python, these stuff meant nothing to me, well, more or less, they are just meaningless.

The biggest problem with programs that take user input is, in most programming languages, when an error occur, the script will stop executing.

This makes a lot of sense in logic, but it is most certainly a very bad experience to the users.

Error handling will help us prevent such embarrassment - to us, as well as the users.

While take input from user, be it using raw_input or a form submitted over HTTP POST, we should not encountered much problem. It means that taking input is quite safe actually.

What is NOT safe is when we try to do something with the user input, which, is always the case - after all, if you are not doing anything about the input data, what is the point of collecting in the first place, right?

This is where things become dangerous - lets say you have a field that accept user to enter their birthday, without checking and converting the data in the front end, there are just countless ways an user may enter its birthday.

Consider these few possible date format: "28th September, 2014" , "28-09-2014", "28/09/2014", "28-9-2014".

While these date formats all make sense, but it would be really hard for us to handle such input, converting them into a format that our database use.

Alright, enough with the back story and logic behind using Error Handling, lets talk about the syntax and how we can actually use them.

There are mainly 4 keywords used in Python to handle errors.

They are "try", "except", "else" and "finally"

Just like any other Python syntax, their meaning and usage are actually quite straightforward.

First, we would need a try block in our code, say we are now going to handle the input data from the birthday field, and we want to try converting it into integer for processing.

However, we do not know if the user would be using a format with only number, therefore, we are not sure if the int( ) conversion function will work.

So, we write something like this:

try:
     data = int(birthday_input_data)

Just like we would normally operate on a safe string.

But yes, we are expecting error, because the user may use a format that contains ASCII characters.

If we try to use the int() function on a string with ASCII letters, Python would raise an error like this:
 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: foobar

As we can see in the last line of the error message, the resulting error is called "ValueError" in python, which is the Error Type we aimed to solve with our next block, so we are going to write it like this:

except ValueError:
      #do something with a data input with ASCII string


Alternatively, if we are not sure what else Error could be cause ahead of time, we can prepare a fallback general-purpose exception case like this:

except:  #with no ValueError class
     #report to the user that a fatal error is caused and the script cannot proceed with the input
     #nicely ask them to try again.


Of course, just like an IF block, we can add multiple layers in the try block to try to handle different possible cases before handing it to the fallback exception.

But what we the code worked the first time? With no error?

In this case, we can add an ELSE block after the TRY block. Like so:

else: #no error
     data.insert_to_database()


Lastly, we do also set a default action to an error handling block at the end to safely close files or re-collect resources. This is done by using the "FINALLY" block at the end, which will always get executed whether there are errors or not.

In our example, we might want to do something like this:

finally:
    db_connection.end()
    #or
    document.close()
 
Thats it.

Again, I wrote these stuff not trying to be a guru, but simply because I am that kind of person who always want to know the rationale behind something before I can fully understand a concept.

The benefit of writing error handling code took sometime to dig into my stubborn head, I hope this article could help someone like me, struggling to understand the purpose of some code.

Search