Facing up to mistakes

INPUT · Slides

Do not let an error stop you

01 / 07

When an error appears, that is where it stops

Until now an error has been something you fix. But things can also fail for reasons other than a mistake in your typing — a number arriving from outside that is not a number, a field that ought to be there and is not.

When an error happens, the program stops on that line. None of the lines after it run. Notice that end never appears below.

print("start")print(10 / 0)print("end")

Result

start
ZeroDivisionError: division by zero

02 / 07

Catch it with try and except

Under try: goes the work that might fail, and under except: goes what to do when it does. Both are indented into blocks.

When an error happens it does not stop there; it jumps to the except block. Once out the other side, the rest carries on as though nothing had happened.

try:    print(10 / 0)except ZeroDivisionError:    print("cannot divide by zero")print("the rest still runs")

Result

cannot divide by zero
the rest still runs

03 / 07

Name a kind, and decide what you catch

After except you name the kind of error you are catching. The names you read in the last group work here as they stand.

Only the kind you named gets caught; anything else stops things as before. This is how you pick up only what you knew could happen.

person = {"name": "Yui"}try:    print(person["hobby"])except KeyError:    print("no such key")

Result

no such key

04 / 07

Take the error itself with as

Write except ValueError as e: and the error itself arrives under the name e.

print it and you get to read the explanation Python put together — the part that came after ValueError: on screen. It is your handle on the cause.

try:    number = int("three")except ValueError as e:    print("could not make a number")    print(e)

Result

could not make a number
invalid literal for int() with base 10: 'three'

05 / 07

Do not swallow the lot

Write except: with no kind after it and every error gets caught. It looks like less work, and it is a thing you must not do.

The example below is only a mistyped variable name. A NameError would have told you at once, but the bare except: quietly swallows it, and all you are left with is "something failed".

What you caught was the failure, not the cause. Leave the kind off and the place you need to fix disappears for good.

price = 300try:    print(pricee)except:    print("something failed")

Result

something failed

06 / 07

else and finally

There are two more blocks you can add. Neither is required, but you should be able to read them.

  • else: … runs only when nothing failed. The place for what happens when it went well
  • finally: … runs last, whether it succeeded or failed. The place for clearing up

else earns its keep when you want to keep the try block short.

try:    number = int("12")except ValueError:    print("could not make a number")else:    print(number * 2)finally:    print("check finished")

Result

24
check finished

07 / 07

Only wrap what you can decide about

Wrap it in a try and the error goes away. But what went away was the error, not the problem. Do nothing inside the except and the program carries on with nobody any the wiser that it failed.

Wrap only what you know can fail and can decide what to do about. When you are unsure, work out what would go in the except first.

Right — some practice at catching.