views:

101

answers:

5

Note: i edited my Q (in the title) so that it better reflects what i actually want to know. In the original title and in the text of my Q, i referred to the source of the thrown exception; what i meant, and what i should have referred to, as pointed out in one of the high-strung but otherwise helpful response below, is the module that the exception class is defined in. This is evidenced by the fact that, again, as pointed out in one of the answers below the answer to the original Q is that the exceptions were thrown from calls to cursor.execute and cursor.next, respectively--which of course, isn't the information you need to write the try/except block.

For instance (the Q has nothing specifically to do with SQLite or the PySQLite module):

from pysqlite2 import dbapi2 as SQ

try:
    cursor.execute('CREATE TABLE pname (id INTEGER PRIMARY KEY, name VARCHARS(50)')
except SQ.OperationalError:
    print("{0}, {1}".format("table already exists", "... 'CREATE' ignored"))
#
cursor.execute('SELECT * FROM pname')
while 1:
    try:
        print(cursor.next())
    except StopIteration:
        break
#

i let both snippets error out to see the exception thrown, then coded the try/finally blocks--but that didn't tell me anything about which module the exception class is defined. In my example, there's only a single imported module, but where there are many more, i am interested to know how an experienced pythonista identifies the exception source (search-the-docs-till-i-happen-to-find-it is my current method).

[And yes i am aware there's a nearly identical question on SO--but for C# rather than python, plus if you read the author's edited version, you'll see he's got a different problem in mind.]

+4  A: 

Usually, I just read the documentation. Part of the documentation for a Python module or function is a list of the exceptions it defines. If it doesn't list anything, I just assume I'm looking for a Python builtin exception.

By the way, the StopIteration exception is the standard way for any Python "iterable" object to signal that you have come to the end of the data it will provide to you. This loop:

cursor.execute('SELECT * FROM pname')
while 1:
    try:
        print(cursor.next())
    except StopIteration:
        break

Can be written as:

cursor.execute('SELECT * FROM pname')
for x in cursor:
    print(x)

EDIT: I have to say that, despite my cheerful confidence that the exceptions would be documented, I cannot find such a list in the Python docstring help or web page help for dbapi2. In that case I guess I just do what you did: Google search for the name of the exception and see what pops out!

steveha
+1  A: 

Usually I wrap the bare minimum that I can in a try..except block, e.g.:

try:
    os.rename('foo', 'bar')
except EnvironmentError:
    ...

try:
    open('bar')
except EnvironmentError:
    ...

This way I can handle each exception appropriately and separately.

Zach Hirsch
+4  A: 

the second [[exception was thrown]] from a python core module

False: it was thrown from a call to cursor.next, exactly like the first one was thrown from a call to cursor.execute -- it's hard to say why you're baldly asserting this counterfactual, but contrary to fact it nevertheless remains.

If you're speaking about, what module an exception class was defined in, as opposed to, as you say, where it was thrown from, that's a completely different thing of course:

try:
  ...whatever...
except Exception, e:
  print "caught an exception defined in module", e.__class__.__module__

Built-in exceptions are actually defined in module exceptions, as this code will also tell you. Of course, once you have the module name (which this snippet gives you), you can further explore, if you wish, e.g. by obtaining the module object (just index sys.modules by module name), etc.

Alex Martelli
+1  A: 

Exception is somehow part of the function signature. The 1st thing to do is to read the documentation, the list of exception it can throw should be given. That's the case in most modules.

In your code, you should catch the minimum exception and just have one general catch at the top of your code (in your main for example) and print somewhere the traceback in order to know where unhandled exceptions comes from.

Then the right way to make sure that you didn't miss an exception is to write unit tests for your code and to cover every possible scenario.

I hope it helps

luc
+1  A: 

You could use python's inspect module and generic Exception handling like so:

from inspect import getmodule
try:
    # attempt some task
except Exception, e:
    print getmodule(e)

Which will spit out the module and its path like so:

<module 'some.module' from '/path/to/some/module.pyc'>
richleland