Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Python Basics Functions and Looping Raising Exceptions

raise ValueError, amount_due in try block, except ValueError as err…

I’m struggling with these three parts of the video, which I must have watched 20 times… Why do we raise (and not except) a ValueError in our original function? Why do we need to move the amount_due expression into the try block? How the heck does ValueError as err even work? I can clearly see how this affects the final output, but I can’t wrap my head around the individual components. I’ve tried looking at other answers here but no luck. Best answer will be given a green tick :)

1 Answer

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,457 Points

Hey nicolaspeterson, good questions all.

Let’s first review the basic concepts of errors. When an unexpected event occurs, an error is “raised”. This raising may be done by internal code (like when int() sees an error) or explicitly by a coder using the raise command. The error says the program can not continue.

In general, all errors will cause a program to halt unless the error is “handled”. Handling an error means being prepared that an error might happen by wrapping code in a try/except block. Theexcept statement lists the exceptions that will be handled locally, all other errors are passed along (possibly ending the program if not handled somewhere else.)

Why do we raise (and not except) a ValueError in our original function?

“Raise” is the process of halting execution, flagging the error, and returning control to the point where this code was called. Since the split_check function doesn’t have control over the arguments passed in, there isn’t a viable option to put in an except block to handle the situation. So a raise is used to notify the calling code.

Why do we need to move the amount_due expression into the try block?

By placing the amount_due expression in a try block, any error raised during the execution of this statement (and all others within the try block) will be evaluated by the matching except statement. Either the int(input…)) or the amount_due statements could raise a ValueError.

How the heck does ValueError as err even work?

The error that is raised has an associated error object. This error object is an instance of the corresponding error class:

>>> ValueError
<class 'ValueError'>
>>> ValueError("hello")
ValueError('hello',)
>>> type(ValueError("hello"))
<class 'ValueError'>

The basic except statement only matches the type of the error object. It does not provide and access to the matched error object. By using the as refinement, the provided label “err” may be used to reference the error object directly. This then allows using the err reference in a str context which will return the “Oh no…” string.

Post back if you need more help. Good luck!!!

This is fantastic, thank you so much! When you put it like this, it makes a lot more sense.