14

i need to identify who raise an exception to handle better str error, is there a way ?

look at my example:

try: os.mkdir('/valid_created_dir') os.listdir('/invalid_path') except OSError, msg: # here i want i way to identify who raise the exception if is_mkdir_who_raise_an_exception: do some things if is_listdir_who_raise_an_exception: do other things .. 

how i can handle this, in python ?

4 Answers 4

21

If you have completely separate tasks to execute depending on which function failed, as your code seems to show, then separate try/exec blocks, as the existing answers suggest, may be better (though you may probably need to skip the second part if the first one has failed).

If you have many things that you need to do in either case, and only a little amount of work that depends on which function failed, then separating might create a lot of duplication and repetition so the form you suggested may well be preferable. The traceback module in Python's standard library can help in this case:

import os, sys, traceback try: os.mkdir('/valid_created_dir') os.listdir('/invalid_path') except OSError, msg: tb = sys.exc_info()[-1] stk = traceback.extract_tb(tb, 1) fname = stk[0][2] print 'The failing function was', fname 

Of course instead of the print you'll use if checks to decide exactly what processing to do.

Sign up to request clarification or add additional context in comments.

8 Comments

@luc, that would be the source but only if available; quoting the docs at docs.python.org/library/…, """A “pre-processed” stack trace entry is a quadruple (filename, line number, function name, text) representing the information that is usually printed for a stack trace. The text is a string with leading and trailing whitespace stripped; if the source is not available it is None.""" As you see function_name is at index 2 in the tuple.
the try/except, try/except solution may be better, but in my case i need to handle, what function raise the exception, so this answer is the best one for me! thanks :)
@boos: how does using two try/ except blocks not tell you which function raised the exception?
@Tom: for sure! using two try/except block tell me what function raised the exception, but it's not what i want. take a look at the code i write up after the @Alex Martelli answer nopaste.voric.com/paste.php?f=4nhemg
@AlexMartelli The extract_tb call here doesn't look right to me - it's giving the topmost frame in the stack, rather than the innermost one where the exception was actually raised, or the next level down where we have access to the called function's name. To get this to work as intended, I had to use stk = traceback.extract_tb(tb, 2); fname = stk[-1][2] instead.
|
8

Wrap in "try/catch" each function individually.

try: os.mkdir('/valid_created_dir') except Exception,e: ## doing something, ## quite probably skipping the next try statement try: os.listdir('/invalid_path') except OSError, msg: ## do something 

This will help readability/comprehension anyways.

3 Comments

depending on the details, the second try... except could possibly go into an else: block from the first one.
This changes the logic slightly - if the mkdir fails because the directory already exists it trys to do the listdir regardless.
Of course I didn't craft the whole solution, just the principle.
1

How about the simple solution:

try: os.mkdir('/valid_created_dir') except OSError, msg: # it_is_mkdir_whow_raise_ane_xception: do some things try: os.listdir('/invalid_path') except OSError, msg: # it_is_listdir_who_raise_ane_xception: do other things .. 

Comments

1

Here's the clean approach: attach additional information to the exception where it happens, and then use it in a unified place:

import os, sys def func(): try: os.mkdir('/dir') except OSError, e: if e.errno != os.errno.EEXIST: e.action = "creating directory" raise try: os.listdir('/invalid_path') except OSError, e: e.action = "reading directory" raise try: func() except Exception, e: if getattr(e, "action", None): text = "Error %s: %s" % (e.action, e) else: text = str(e) sys.exit(text) 

In practice, you'd want to create wrappers for functions like mkdir and listdir if you want to do this, rather than scattering small try/except blocks all over your code.

Normally, I don't find this level of detail in error messages so important (the Python message is usually plenty), but this is a clean way to do it.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.