Handling exceptions

39 views
Skip to first unread message

yann19

unread,
Nov 14, 2016, 9:18:57 PM11/14/16
to Python Programming for Autodesk Maya
I have 2 scripts, `script_A` and `script_B` where `script_B` is my main code.
In `B`, I have the following commands...

class dialogManager(QtGui.QDialog):
   
def __init__(self, type="", parent=None):
       
...
        things_to_exclude
= script_A.get_list_of_exclusions(type)
        things_to_check
= script_A.get_list_of_checked_items(type)
       
...


Generally, the function contents for both `get_list_of_exclusions` and `get_list_of_checked_items` are the same with the exception of its name..
def get_list_of_exclusions(type):
    file_path
= os.path.join(
        config_path
, file_template.format(type=type)
       
)
   
if not os.path.exists(file_path):
       
raise Exception('Config does not exist for the exclusions!'
                       
'\n{0}'.format(file_path)
                       
)
   
with open(file_path) as mapping_file:
        mapping_data
= json.load(file_path)
   
return file_path

Though it may be a bit overkill but I was thinking of writing a check like what happens if `type` is not defined or if the developers did not entered in a valid `type`...
class dialogManager(QtGui.QDialog):
   
def __init__(self, type="", parent=None):
       
...
       
if type == "":
           
raise IOError("Nothing is defined for the type. Please contact dev!")
            sys
.exit()
        things_to_exclude
= script_A.get_list_of_exclusions(type)
        things_to_check
= script_A.get_list_of_checked_items(type)
       
if not things_to_exclude or things_to_check:
           
# How do I handle that the Exceptions that were already raised, supposed if the files does not exists etc.
       
...
But I am stumped at the portion of getting the already raised Exceptions... I checked online and derived answers of using try...except.. is that the only way to do so?

Justin Israel

unread,
Nov 14, 2016, 9:44:21 PM11/14/16
to python_in...@googlegroups.com
First off, I will definitely suggest never calling sys.exit() from library code (code that gets imported into something else). You most likely don't want to trigger termination of the process because of a parameter not being passed correctly. 

It should be fine to add an extra check of your "type" parameter if you can do a more specific check and raise a more specific error message at that point in time, instead of letting errors bubble up from other calls that may have less context. Also it can be useful if you want to prevent more expensive operations from happening when they don't need to, such as reading from the filesystem only to find out that you had a bad parameter to begin with. But an IOError is usually reserved for input/output communication failures such as file system and network reads that are external to your code. Maybe a ValueError or TypeError would be more suitable here.

try/except is exactly how you catch, handle, and optionally re-raise exceptions in Python. 

It would look something like:

try:
    get_list_of_exclusions()
except SomeKnownExceptionType as e:
    print "I got an exception:", e
    # re-raise the original exception
    raise

"SomeKnownExceptionType" is the type of exception you expect to see from calling your function. Raising the generic Exception type in your function is probably not helpful. It looks like you should be raising an IOError, which you know will mean a problem with the filesystem (non existant file in this case). 

See this doc on how to raise and catch exception:

Justin


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/b30c4134-210f-44aa-a5c2-31e44204bcb4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

yann19

unread,
Nov 15, 2016, 2:16:09 AM11/15/16
to Python Programming for Autodesk Maya
Hi Justin, thanks for getting back!
Earlier you have mentioned that in those two functions I have, raising Exception is not ideal. In that case, will it do any better if I used IOError within the init function and use that instead?

Also, a rather noob question from me. While before I do or know any handling, if I try to 'break' my code, I can know what error to use, eg. valueerror etc.
But as there are times such traceback error is not shown , using my scenario, if type is an empty string, I do not know which to use as it prompt of no such error type. How do I know which is the correct to use?
I use ioerror, did some trial and error, seems to work and hence did not thought much of it..

Cesar Saez

unread,
Nov 15, 2016, 12:34:54 PM11/15/16
to python_in...@googlegroups.com
Hi there,
i hope this comment does not become too controversial, but I think there are several things to consider on your design.

Let star by the surface and dig deeper as we go.
- Does it make sense initialize your class by passing a type == "" ?
If not, do not use a keyword argument without a good reason, take advantage of python builtin validation and require a `type`.
(btw, `type` is not the best name as your variable will override the builtin `type()` within that block of code)

- Is init the right place to validate inputs? In my opinion is not because at that point the instance was already created (`self` refers to the instance)... I highly recommend to validate inputs in a constructor (i.e. a classmethod returning an instance would do it). Creating an instance just to destroy it a few lines later doesn't make much sense in my view.

- This is perhaps a more important question to ask yourself: How would you test your class? Can you make it non dependent on the entire filesystem?
It's all good to have an auto-discovery mechanisms (or whatever you are cooking there), but I wouldn't do it as an init dependency because it compromise the entire design. Instead of that, I would pass in whatever the discovery get as an argument to a constructor (i.e. if you are getting serialized data from json/yaml/xml/whatever files, I would get/parse the file and pass in that python data, avoiding hidden dependencies and making the system way more portable/testable/decoupled).

Cheers!

Justin Israel

unread,
Nov 15, 2016, 3:27:53 PM11/15/16
to python_in...@googlegroups.com
On Tue, Nov 15, 2016 at 8:16 PM yann19 <yang...@gmail.com> wrote:
Hi Justin, thanks for getting back!
Earlier you have mentioned that in those two functions I have, raising Exception is not ideal. In that case, will it do any better if I used IOError within the init function and use that instead?

Raising an exception in itself is fine. I was specifically saying that the base Exception is not very descriptive. You should try and use the most specific builtin Exception type that matches your issue, as defined in: https://docs.python.org/2/library/exceptions.html

If your error really is related to filesystem input/output issues, then maybe IOError is ok, but it won't make much sense to the caller who doesn't know too much about the implementation of your dialog. Maybe it is better to not perform filesystem operations from within a constructor of a class, and defer those for when your dialog is being shown? If you know the type parameter is wrong right away, you can raise the TypeError or ValueError. But if its a good value, then you could just raise the IOError at a later point when it is shown. Or maybe you don't raise and you choose to display nothing and to log the error instead of failing.
 

Also, a rather noob question from me. While before I do or know any handling, if I try to 'break' my code, I can know what error to use, eg. valueerror etc.
But as there are times such traceback error is not shown , using my scenario, if type is an empty string, I do not know which to use as it prompt of no such error type. How do I know which is the correct to use?
I use ioerror, did some trial and error, seems to work and hence did not thought much of it..

When doing exception handling, you should know the types of exceptions that can be raised either from knowing explicitly what kind of operations you are doing (such as file system operations) or via the documentation of the functions you are calling that tell you what possible exceptions can be raised. Of course exceptions, being exceptions, can be raised unexpectedly. And once you find those problems you should either fix a bug or catch and handle that now expected exception type.
 

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages