If have a function were I request some data from a website but when I get an error I want to print the error and restart my code. But I don't know the exact code, can please someone help me? This is a code example:
import time
input1 = input("Blabla: ")
def repeat():
try:
if input1 == "123":
raise "Error: 123"
except Exception as e:
print(e)
time.sleep(5) # Wait 5 seconds
repeat() # Rerun code
repeat()
When I run this code I get the error 'exceptions must derive from BaseException'. Can someone help me?
You can't just raise random strings as an exception. If you want to raise a general exception without defining a relevant type, just raise Exception, replacing:
raise "Error: 123"
with:
raise Exception("Error: 123") # The "Error: " should probably be removed
Alternatively, if you can use a more specific error, do so. If 123 is invalid because the value is wrong, use ValueError instead of Exception. If there is some more specific reason, make a subclass to make it easier for others to catch, e.g. (at top level in the module):
class SpecialValueError(ValueError):
pass
so you can do:
raise SpecialValueError("Error: 123")
and people can catch it specifically, or via plain except ValueError:, except Exception:, etc.
Right now you are printing the error object's str while you need to print it's representation
Try this:
def repeat():
try:
if input1 == "123":
raise Exception("Error: 123") # You need to use an Exception class
except Exception as e:
print(repr(e)) # Notice I added repr()
time.sleep(5)
repeat()
Exception's Representation vs Exception's String
String:
try:
raise Exception("Exception I am!")
except Exception as e:
print(e)
# Output: Exception I am!
Representation:
try:
raise Exception("Exception I am!")
except Exception as e:
print(repr(e))
# Output: Exception('Exception I am!')
Related
Instead of calling the exception directly, I have seen it is subclassed with nothing in it or a pass statement. How does it help Python internally to subclass a base class, in this manner? Does it change namespace or signature? How?
class ACustomException(Exception):
pass
class BCustomException(Exception):
pass
Raising Exception is like telling the doctor "Something's wrong" and then refusing to answer any questions. Compare:
try:
with open("foo.json", "rt") as r:
new_count = json.load(r)["count"] + 1
except Exception:
# Is the file missing?
# Is the file there, but not readable?
# Is the file readable, but does not contain valid JSON?
# Is the file format okay, but the data's not a dict with `count`?
# Is the entry `count` there, but is not a number?
print("Something's wrong")
# I don't care. You figure it out.
and
try:
with open("data.json", "rt") as r:
new_count = json.load(r)["count"] + 1
except FileNotFoundError:
print("File is missing.")
except PermissionError:
print("File not readable.")
except json.decoder.JSONDecoderError:
print("File is not valid JSON.")
except KeyError:
print("Cannot find count.")
except TypeError:
print("Count is not a number.")
If you are making a library, you can use the predefined exception classes where appropriate — but sometimes you need to communicate errors that Python creators never thought about, or you need to make a finer distinction than the existing exceptions do. This is when you'd create a custom exception.
For example, Django will define django.contrib.auth.models.User.DoesNotExist exception to communicate that the code tried to look for a User in the database, but no User matching the given criteria could be found. Being able to catch django.contrib.auth.models.User.DoesNotExist is like being a doctor, and getting a patient that not only tells you what hurts, but brings X-rays and a printed family history with them.
When you're handling exceptions with try-except, you're catching them by name, so having specific names helps you handle them.
For example, if a function raises Exception for any error, the catching logic gets complicated:
def foobar():
if FOO:
raise Exception('FOO happened')
elif BAR:
raise Exception('BAR happened')
try:
foobar()
except Exception as e:
if e.args == ('FOO happened',):
print('Handling FOO')
elif e.args == ('BAR happened',):
print('Handling BAR')
else:
raise
On the other hand if you have subclassed exceptions, the catching logic is simple:
class FooError(Exception):
pass
class BarError(Exception):
pass
def function():
if FOO:
raise FooError('FOO happened')
elif BAR:
raise BarError('BAR happened')
try:
function()
except FooError:
print('Handling FOO')
except BarError:
print('Handling BAR')
It helps with determining 'what' the traceback issue is referring to in case of maybe a web service that you maybe running, so it's not low-level or the generic errors you normally get back rather the exception class that would be used.
To be more specific with an example:
val = int(input('Enter a number:'))
try:
val *= val
except ValueError as e:
raise e
print(val)
### ValueError will be raised if user inputs something other than a number
### this raise e will return the actual error message saying
### ValueError: invalid literal for int() with base 10: 'ok'
In your case, you could still raise your exception keeping ValueError as the except to be handled for, like this:
val = int(input('Enter a number:'))
try:
val *= val
except ValueError as e:
raise ACustomException('some debug statement referring to the cause of the error')
print(val)
### now this will raise your exception class besides the ValueError exception, with a debug statement if you choose to have one in it.
tl;dr
How to catch different exceptions of the same type but with different messages?
Situation
In ideal world I would handle exceptions like this:
try:
do_something()
except ExceptionOne:
handle_exception_one()
except ExceptionTwo:
handle_exception_two()
except Exception as e:
print("Other exception: {}".format(e))
But external code that I'm using can can throw, in my usage, two exceptions. Both are ValueErrors but have different message. I'd like to differentiate handling them. This is the approach that I tried to take (for easier presentation of my idea I raise AssertionError):
try:
assert 1 == 2, 'test'
except AssertionError('test'):
print("one")
except AssertionError('AssertionError: test'):
print("two")
except Exception as e:
print("Other exception: {}".format(e))
but this code always goes to the last print() and gives me
Other exception: test
Is there a way to catch exceptions this way? I'm assuming this is possible because Python lets me specify MESSAGE when catching exception ExceptionType('MESSAGE') but in practice I didn't manage to make it work. I also didn't find a definitive answer in the docs.
I would go for something like this:
try:
do_the_thing()
except AssertionError as ae:
if "message A" in ae.value:
process_exception_for_message_A()
elif "message B" in ae.value:
process_exception_for_message_B()
else:
default_exception_precessing()
I'm wondering if there is a keyword for "all" in python except. I've ran into this seemingly simple problem:
try:
#do stuff
except any as error:
print('error: {err}'.format(err=error))
I know that you can do except: to catch all errors, but I don't know how to add an as keyword to get a printable object. I want to catch any error and be able to get an object for use in printing or something else.
You can catch almost anything this way:
try:
#do stuff
except Exception as error:
print('error: {err}'.format(err=error))
But to catch really everything, you can do this:
import sys
try:
#do stuff
except:
err_type, error, traceback = sys.exc_info()
print('error: {err}'.format(err=error))
Yes, just catch Exception:
except Exception as ex:
# phone num
try:
phone=soup.find("div", "phone-content")
for a in phone:
phone_result= str(a).get_text().strip().encode("utf-8")
print "Phone information:", phone_result
except ValueError:
phone_result="Error"
My program stops when there is a uni-code error but i want to use try except to avoid terminating the program. how can i do it?
I get different types of errors. i want something which just doesnt terminate the loop no matter whatever the error. just i want to skip the part of the loop which has error
By using
try:
...
except:
...
You could always catch every error in your try block attempt. The problem with THAT is that you'll catch even KeyboardInterrupt and SystemExit
However, it's better to catch Errors you're prepared to handle so that you don't hide bugs.
try:
...
except UnicodeError as e:
handle(e)
At a minimum, you should at least be as specific as catching the StandardError.
Demonstrated using your code:
try:
phone=soup.find("div", "phone-content")
for a in phone:
phone_result= str(a).get_text().strip().encode("utf-8")
print "Phone information:", phone_result
except StandardError as e:
phone_result="Error was {0}".format(e)
See the Exception Hierarchy to help you gauge the specificity of your error handling.
http://docs.python.org/2/library/exceptions.html#exception-hierarchy
I think you can try something like this first:
try:
whatever()
except Exception as e:
print e
Then you will get your desired(!) exception [if it already exists], and then change it to except somethingelse
Or you can go for custom exception which will look something like following, but you have raise it where necessary:
class ErrorWithCode(Exception):
def __init__(self, code):
self.code = code
def __str__(self):
return repr(self.code)
I am trying to figure out how I would print an exception if I don't know what the exception is in the first place. How would I do the following?
try:
some_command
except:
print *full_exception_trace*
Like the tutorial says.
try:
something()
except SomeException as e:
something_else(e)
You may find traceback useful.
def exception(self)
try:
Something.objects.all()
except Exception, err:
print err.message #(if you want)
#raise err
raise # The 'raise' statement with no arguments inside an error
# handler tells Python to re-raise the exception with the
# original traceback intact
err.message will give you the reason of the exception
The traceback module's print_exc() function seems to be what you want. Docs