use str
try:
some_method()
except Exception as e:
s = str(e)
Also, most exception classes will have an args attribute. Often, args[0] will be an error message.
It should be noted that just using str will return an empty string if there's no error message whereas using repr as pyfunc recommends will at least display the class of the exception. My take is that if you're printing it out, it's for an end user that doesn't care what the class is and just wants an error message.
It really depends on the class of exception that you are dealing with and how it is instantiated. Did you have something in particular in mind?
Answer from aaronasterling on Stack Overflowuse str
try:
some_method()
except Exception as e:
s = str(e)
Also, most exception classes will have an args attribute. Often, args[0] will be an error message.
It should be noted that just using str will return an empty string if there's no error message whereas using repr as pyfunc recommends will at least display the class of the exception. My take is that if you're printing it out, it's for an end user that doesn't care what the class is and just wants an error message.
It really depends on the class of exception that you are dealing with and how it is instantiated. Did you have something in particular in mind?
Use repr() and The difference between using repr and str
Using repr:
>>> try:
... print(x)
... except Exception as e:
... print(repr(e))
...
NameError("name 'x' is not defined")
Using str:
>>> try:
... print(x)
... except Exception as e:
... print(str(e))
...
name 'x' is not defined
Question: How to convert Python Exception (PyErr) into string for logging
Exception handling in Python - Am I doing this wrong (and why?) - Software Engineering Stack Exchange
How to use Try and Except to detect if user has entered stringb or integer?
Print exception notes - in repr(exc) or otherwise - Ideas - Discussions on Python.org
User input sucks. You can't trust those users to get anything right, and so you've got to handle all kinds of special cases that make your life difficult. Having said that, we can minimize the difficulty with general principles.
Validate early, not often
Check input for validity as soon as it read into your program. If you read in a string that should be a number, convert it into a number right away and complain to the user if it isn't a number. Any rogue data you don't verify at input will make its way into the rest of the program and produce bugs.
Now, you can't always do this. There will be cases where you can't verify the correct properties right away, and you'll have to verify them during later processing. But you want as much verification to happen as early as possible so that you have your special cases around input logic centralized to one location as much as possible.
Use Schemas
Let's consider a function that parses some json.
def parse_student(text):
try:
data = json.parse(text)
except ValueError as error:
raise ParseError(error)
if not isinstance(data, dict):
raise ParseError("Expected an object!")
try:
name = data['name']
except KeyError:
raise ParseError('Expected a name')
if not isinstance(name, dict):
raise ParseError("Expected an object for name")
try:
first = name['first']
except KeyError:
raise ParseError("Expected a first name")
if not isinstance(first, basestring):
raise ParseError("Expected first name to be a string")
if first == '':
raise ParseError("Expected non-empty first name")
That was a lot of work just to extract the first name, let alone any other attributes. We can make this a lot better if we can use a json-schema. See: http://json-schema.org/.
I can describe what my student object looks like:
{
"type": "object",
"properties": {
"name": {
"type": "object",
"properties": {
"first" : {
"type" : "string"
}
},
"required": "first"
},
}
"required": ["name"]
}
When I parse I then do something like:
def parse_student(text):
try:
data = json.parse(text)
except ValueError as error:
raise ParseError(error)
try:
validate(data, STUDENT_SCHEMA)
except ValidationError as error:
raise ParseError(error)
first = data['name']['first']
Checking against the schema verifies most of the structure that I need. If the user input does not match the schema, the schema validator will produce a nice error message explaining exactly what was wrong. It will do so far more consistently and correctly then if I wrote the checking code by hand. Once the validation has been passed, I can just grab data out of the json object, because I know that it will have the correct structure.
Now, you probably aren't parsing JSON. But you may find that you can do something similar for your format that lets you reuse the basic validation logic across the different pieces of information that you fetch.
You can probably simplify your code by centralising the try/except validation of function args, and the conversion of exceptions to your exception class, into one or two decorators, which you apply to each of your methods and functions. google for python decorators for exceptions, and python decorators to validate args and you'll find stackoverflow examples like this and this.
You often don't need to explicitly validate method arguments as your code is going to cause exceptions naturally, and this might be good enough, as you cannot test for all eventualities.
Remember when writing a script, that often that your code will be even more useful if someone can include it as a library module, so make the main be specific to what a user would like from the command line, but in the library part don't try too hard to obscure where an exception stems from and so on.
Stuck on this part of the practice project in the book automate the boring the stuff. It asks you to add try and except statements to detect if the user has entered an integer or noninteger string but doesn't explain anywhere the actual syntax for how to do that.