Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I know which exceptions might be thrown from a method call?

Is there a way knowing (at coding time) which exceptions to expect when executing python code?

I end up catching the base Exception class 90% of the time since I don't know which exception type might be thrown (reading the documentation doesn't always help, since many times an exception can be propagated from the deep. And many times the documentation is not updated or correct).

Is there some kind of tool to check this (like by reading the Python code and libs)?

like image 681
GabiMe Avatar asked Oct 19 '09 21:10

GabiMe


People also ask

Which exceptions may be thrown from that method?

Any method can throw any unchecked exception. Checked exceptions are any exceptions derived from java. lang. Exception (and including Exception itself) except java.

How do you decide if an exception should be thrown in a method?

An exception should be thrown when a function experiences a failure, i.e., an error. A function is a unit of work, and failures should be viewed as errors or otherwise based on their impact on functions.

Which exceptions can be thrown?

Before you can catch an exception, some code somewhere must throw one. Any code can throw an exception: your code, code from a package written by someone else such as the packages that come with the Java platform, or the Java runtime environment.


2 Answers

I guess a solution could be only imprecise because of lack of static typing rules.

I'm not aware of some tool that checks exceptions, but you could come up with your own tool matching your needs (a good chance to play a little with static analysis).

As a first attempt, you could write a function that builds an AST, finds all Raise nodes, and then tries to figure out common patterns of raising exceptions (e. g. calling a constructor directly)

Let x be the following program:

x = '''\ if f(x):     raise IOError(errno.ENOENT, 'not found') else:     e = g(x)     raise e ''' 

Build the AST using the compiler package:

tree = compiler.parse(x) 

Then define a Raise visitor class:

class RaiseVisitor(object):     def __init__(self):         self.nodes = []     def visitRaise(self, n):         self.nodes.append(n) 

And walk the AST collecting Raise nodes:

v = RaiseVisitor() compiler.walk(tree, v)  >>> print v.nodes [     Raise(         CallFunc(             Name('IOError'),             [Getattr(Name('errno'), 'ENOENT'), Const('not found')],             None, None),         None, None),     Raise(Name('e'), None, None), ] 

You may continue by resolving symbols using compiler symbol tables, analyzing data dependencies, etc. Or you may just deduce, that CallFunc(Name('IOError'), ...) "should definitely mean raising IOError", which is quite OK for quick practical results :)

like image 59
Andrey Vlasovskikh Avatar answered Oct 13 '22 04:10

Andrey Vlasovskikh


You should only catch exceptions that you will handle.

Catching all exceptions by their concrete types is nonsense. You should catch specific exceptions you can and will handle. For other exceptions, you may write a generic catch that catches "base Exception", logs it (use str() function) and terminates your program (or does something else that's appropriate in a crashy situation).

If you really gonna handle all exceptions and are sure none of them are fatal (for example, if you're running the code in some kind of a sandboxed environment), then your approach of catching generic BaseException fits your aims.

You might be also interested in language exception reference, not a reference for the library you're using.

If the library reference is really poor and it doesn't re-throw its own exceptions when catching system ones, the only useful approach is to run tests (maybe add it to test suite, because if something is undocumented, it may change!). Delete a file crucial for your code and check what exception is being thrown. Supply too much data and check what error it yields.

You will have to run tests anyway, since, even if the method of getting the exceptions by source code existed, it wouldn't give you any idea how you should handle any of those. Maybe you should be showing error message "File needful.txt is not found!" when you catch IndexError? Only test can tell.

like image 36
P Shved Avatar answered Oct 13 '22 06:10

P Shved