Python exception base class vs. specific exception - python

I just wonder, when using try.. except, what's the difference between using the Base class "Except" and using a specific exception like "ImportError" or "IOError" or any other specific exception. Are there pros and cons between one and the other?

Never catch the base exception. Always capture only the specific exceptions that you know how to handle. Everything else should be left alone; otherwise you are potentially hiding important errors.

Of course it has advantages using the correct exception for the corresponding issue. However Python already defined all possible errors for coding problems. But you can make your own exception classes by inheriting from the Exception class. This way you can make more meaningful errors for spesific parts of your code. You can even make the expections print errors like this.
SomeError: 10 should have been 5.
Provides easier debugging of the code.
For more info.

Related

Python Exception Handling : Is there a method to know what type of exceptions my code can possibly throw?

I have a code, lets say :
'''
try:
somecode()
except Exception as e:
somelog()
'''
Is there a way to find out all the possible exceptions somecode() can throw so that I can handle them in an appropriate order.
While you may not always be able to know every error that may happen, you can do quite a bit by thinking of common cases. This link is a good starter's guide with examples:
https://www.pythonforbeginners.com/error-handling/exception-handling-in-python1
For raising exceptions you predict in your own functions, this is a good starter guide:
https://www.programiz.com/python-programming/user-defined-exception
Finally, when you're working with built in functions or packages, they usually document what exceptions they raise. For example, look at the built in page for Python
https://docs.python.org/3/library/functions.html
And ctrl-f ValueError. A lot of docs will tell you what exceptions they raise but beyond that it's up to you to anticipate and guess based on your implementation and usage.
Hope that helps!
There are not so many exception types which you may have to consider for a single case. In case you are trying to access a file or accessing the database, the options are very few. The best practice is to keep track with the documentation. This will not take much time to know the name of the exception.
https://docs.python.org/3/tutorial/errors.html

Security issue in catching exceptions in outside methods? Python

Is there a security issue in catching exceptions through a separate function? For example if I catch an exception in class:
def my_function(some_variable):
try:
int(some_variable)
except ValueError:
sys.exit()
#other code running
As opposed to passing it through some sort of method.
def my_function(some_variable)
check_error(some_variable) #this does the try/except
#other code running
def check_error(some_variable)
#does the check
Is there a flaw or vulnerability that can be exploited in one or the other, by memory, etc, or is the two methods shown above essentially the same thing. I believe that python deals with all memory handling automatically. I could be wrong. However, I want to know is there a reason why it is good practice to catch exceptions in method or in an outside method as shown in the two code samples above.
I understand if there is a lot of checking it is good for an exception method for readability and modularity, but is it good for security?
Also this might be a better question to put in chat, but I don't have that capability yet. Thanks in advance.

Python - Why is an exception type needed to be put after an 'except'? [duplicate]

This question already has answers here:
Should I always specify an exception type in `except` statements?
(7 answers)
How to properly ignore exceptions
(12 answers)
Closed 8 years ago.
When you use try/except in python, why do you need an exception type to be named after except? Wouldn't it be easier to just catch all exceptions?
try:
#dosomething
except Exception:
#dosomething
Why is the 'Exception' needed after except?
Because you might handle different exceptions different ways.
For example, if you're attempting a network operation, and the network address you're trying to reach can't be resolved, that's likely due to user error, and you'll want to get the user involved, while some other kinds of errors can simply be retried after a short wait.
It's a good practice in exception handling to handle only the narrowest set of exceptions you expect at any one point in the code, and to only catch those exceptions that you're sure you know how to handle. A catch-all exception handler violates this principle.
From a purely syntactic point of view, this is acceptable code:
try:
# Do something
except:
print "Something went wrong."
HOWEVER, it's not a very good idea to do this a lot of the time. By catching all exceptions and not even saving the name, you're losing all information about where the error was. Just seeing Something went wrong. printed out is both useless and frustrating. So even if you don't want to handle each exception individually, you'd want to save the exception information at the very least.
try:
# Do something.
except Exception, e:
print "Encountered error " + str(e) + " during execution. Exiting gracefully."
The above code is something you might do if you absolutely can't let your program exit abruptly, for example.
EDIT: changed the answer to clarify that it's a bad idea, though possible.
Why and how to catch exceptions
Exceptions are really helpful, but they shall be handled in different manner depending on what code
you write.
Core distinction is, if your code is top level one (last resort to handle exceptions) or inner one.
Another aspect is, if some exceptions are excepted or unexpected.
Expected exceptions (like file, you are trying to use is missing) shall be handled, if the code has
a chance to do anything about it.
Unexpected exceptions shall not be handled unless you have to do so in top level code.
Handling exceptions in top level code
If it does not matter, that your code throws a bit ugly stack trace under some circumstances, simply
ingore the unexpected exceptions. This is mostly very efficient, as the code is kept simple, and
stack trace give you good chance to find out, what went wrong.
If you have to make your script "well behaving" - you could catch the exception and print some nice
looking excuse for what went wrong.
Handling exceptions in lower level code (modules, functions)
In your lower level code, you shall catch all expected exceptions, and the rest shall be ignored and
thrown up to higher levels, where is better chance to handle it properly.
If you have no expected exception, simply do not use try .. except block.
Printing some excuses from lower level code is mostly inappropriate (higher level code has no chance
t silence your printouts.
To your question - why except Exception
except with explicitly mentioned type of exception is the only solution to use for expected types
of exceptions. Without mentioning the type (or types), you are catching all and this is bad habit
unless you are in top level code.
As usual, there are exceptions to the recommendations above, but they are occurring less often than one
usually expects.
Different exceptions require different fixing. For example, when I was writing a python irc bot, i would have one exception for invalid access to a string, and that code in the except would try to remedy it. I also had one for bad sockets that would try to deduce why it went bad and fix it. I can't have these under one exception because they are fixed differently

Treating language errors and runtime errors differently in python

I have a decent sized code in python which I changed a bit and now I see that when executing the code, the script does not bail on language errors like missing function definitions.
I did not think it was possible to continue running a script with missing function definition. I used a function in one place with the intention of actually defining the function before running but forgot about it and ran the code. To my surprise I just got the following line printed to the console --
Worker instance has no attribute update_parse_status
Where Worker is the class I was supposed to add the update_parse_status() call to.
I realized that I had a try and a generic catch all exception handler around the code in question like this --
try:
Worker.update_parse_status()
except Exception as e:
print e
So python just throws a AttributeError and I was unknowingly catching it. It taught me a valuable lesson to not have catch all exception handlers. Also coming from a compiled language is there a better way to handle this? I mean, can I some how make sure python just exits on language errors? It will be very helpful to atleast weed out the obvious bugs (though I understand that bad code got me into this situation).
In python all names are looked up at runtime. Therefor, what you refer to as "language" errors are no different than runtime errors.
This makes python different than many other languages. One of the advantages of that fact is that you can easily customize the way names are looked up (e.g. by overriding class's __getattr__) for example.
You can make use of analyzers (e.g. pyflakes is pretty cool, but there are many others) to detect some of the errors before running your program, but no tool would be able to detect all.
You already answered your own question.
Don't catch exceptions if you don't need too ...
except Exception is dangerous
if you must catch the exception but use some logging mechanism to track it down.
Finally, make sure python just exits on errors: don't catch exceptions where it is not needed to guarantee the flow of the program.
Python, being an interpreter, does this. The best way to counter this is unit testing. The unittest module can help here, and setuptools can run these tests for you. You can package these with your source distribution, as well.
Of course, as you discovered, never use the catch-all exception. That also masks errors that unit tests could catch. You can also run your code under a debugger when developing it so this can be tracked more easily as well. Using the catch-all also makes debugging harder (or even impossible).
You can also do static analysys, using tools such as pylint or pyflakes.

How can I handle a boto exception in python?

How can I wrap a boto.storage_uri() call in python so I can handle possible exceptions?
Your question about Boto is a good one, not not easy to answer. The Boto exception hierarchy is poorly designed, and ultimately the only way to determine what the exception you want to trap is requires looking at the boto source code.
For example if you look at (on Ubuntu) /usr/share/pyshared/boto/exception.py you will see that there are two broad classes:
boto.exception.BotoClientError
boto.exception.BotoServerError
Many of the exceptions are derived from these two, though the concept of "Client" and "Server" is not very well defined and you probably would want to check for both to be sure as many exceptions can happen unexpected (as usual). However, exceptions such as boto.exception.NoAuthHandlerFound is derived directly from Exception and therefore you would have to check for it separately.
Unfortunately from looking at the code, it appears that there is neither consistency nor much care in defining the exception hierarchy in Boto, which is a flaw in Boto's design which unfortunately requires that you rely on more broad exception checking than would normally be recommended.
The first question is what exceptions is this call likely to generate? You do not want to make a blanket exception handler in any language. You should first take a look at the Boto documentation to see if it documents the exceptions you might see from a given call, but if not I would first try:
try:
uri = boto.storage_uri()
except Exception, e:
print e
Or log the exception (with the logging package exception method), but either way you want to take note of what types of exceptions you see while you're testing and whether you should handle any of them specially. You also may want to review the Python Tutorial section on Exceptions and Errors.
Looking at the boto3 source, Boto3Error is declared as the base of all boto errors. So, you can probably do this:
try:
boto.storage_uri()
except Boto3Error:
# handle errors

Categories

Resources