What is the proper method of printing Python Exceptions? - python

except ImportError as xcpt:
print "Import Error: " + xcpt.message
Gets you a deprecation warning in 2.6 because message is going away.
Stackoverflow
How should you be dealing with ImportError? (Note, this is a built-in exception, not one of my making....)

The correct approach is
xcpt.args
Only the message attribute is going away. The exception will continue to exist and it will continue to have arguments.
Read this: http://www.python.org/dev/peps/pep-0352/ which has some rational for removing the messages attribute.

If you want to print the exception:
print "Couldn't import foo.bar.baz: %s" % xcpt
Exceptions have a __str__ method defined to create a readable version of themselves. I wouldn't bother with "Import Error:" since the exception will provide that itself. If you add text to the exception, make it be something you know based on the code you were trying to execute.

Related

Python catching errors from package, finding out which sublibrary exception belongs in

I've encountered several times now that I want to catch an exception that was raised by some library, but that it takes some time to actually find where that exception resides.
Example
Suppose I want to read some csv-file, except the seperator can be one of 2 values. I'd use:
import pandas
try:
mydf=pandas.read_csv('Somefile.csv', sep=';')
if not someValidityChecks(mydf): raise myExc.NotValidError
except:
mydf=pandas.read_csv('Somefile.csv', sep=',')
Now this code catches any and all exceptions, which is not really what I want (it's not Zen).
What I actually want, is to catch NotValidError, and the exception that is thrown by pandas if it encounters some invalid csv: ParserError.
But except myExc.NotValidError, ParserError won't work, because ParserError is not defined in my context. Instead, it should be pandas.errors.ParserError.
The question
Is there some quick way to find out where an exception is defined?
That there is a ParserError that I should catch, is easy enough to find out by simply letting it be thrown, the errormessage clearly shows that. Yet to find out where that error comes from, I have to dig into the stacktrace, and look at all the imports where it could be defined.
Now pandas doesn't have the most complicated structure, and guessing that the error could be in pandas.errors isn't that hard, but it still takes some time checking. Other libraries might have defined their exceptions at some more unexpected place, or spread all around. It should be easy enough to find out what actual error (including package) was thrown, right?
Environment
I'm working with Anaconda/Spyder 3.3.2, with Python 3.7
The quick way to do this is to print the module of the exception and it's qualified name:
try:
# thing that generates exception
raise pd.errors.ParserError
except Exception as e:
print(type(e).__module__, type(e).__qualname__)
pandas.errors ParserError

How to handle exception with parameters in Python

In Python 3.x, what is the correct syntax to handle exceptions that have parameters.
I'm specifically trying to handle WriteError documented on this page.
I'm writing the code to handle it as:
except pymongo.errors.WriteError(err, code, dtls):
logging.error("DB Write Error. err={}; code={}; dtls={}".format(err, code, dtls))
This is not working.
I even had a look at the Erros and Exceptions documentation. But could not find it there.
Can you please tell me the correct way to handle these sort of exceptions?
You catch the error first, then examine its attributes (reraising the exception if it isn't one you want to handle). There is no pattern matching on the contents of the exception.
except pymongo.errors.WriteError as exc:
logging.error("DB WriteError. err={}; code={}; dtls={}".format(exc.err, exc.code, exc.dtls))
The except block just needs the exception's type. Within the block you could, of course, use its attributes if you wish:
except pymongo.errors.WriteError as e:
logging.error("DB Write Error. err={}; code={}; dtls={}".format(e.err, e.code, e.dtls))

Any way to save a traceback object in Python

I was looking to possibly try and save a traceback object and somehow pickle it to a file that I can access. An example of a use case for this is if I am submitting some python code to a farm computer to run and it fails, it would be nice to be able to open a session and access that traceback to debug the problem rather than just seeing a log of the traceback. I do not know if there is any sort of way to do this but thought it would be worth asking why it couldn't if so.
okay so you can use traceback.print_exception(type, value, traceback[, limit[, file]]) and save it in a text or json or you can refer to docs
if you find it helpful please mark it correct or upvote thanx..:)
Depending on how you've written your code, the try statement is probably your best answer. Since any error is just a class that inherits Python's builtin Exception, you can raise custom errors everywhere you need more information about a thrown error. You just need to rename your errors or pass in an appropriate string as the first argument. If you then try your code and use the except statement except CustomError as e, you can pull all the information you want out of e in the except statement as a regular instance. Example:
Your code would be:
def script():
try: codeblock
except Exception as e: raise Error1('You hit %s error in the first block'% e)
try: codeblock 2
except Exception as e: raise Error2('You hit %s error in the second block' % e)
try: script()
except Exception as e:
with open('path\to\file.txt','w') as outFile:
outFile.write(e)
The last part is really nothing more than creating your own log file, but you have to write it down somewhere, right?
As for using the traceback module mentioned above, you can get error information out of that. Any of the commands here can get you a list of tracebacks:
http://docs.python.org/2/library/traceback.html
On the otherhand, if you're trying to avoid looking at log files, the traceback module is only going to give you the same thing a log file would, in a different format. Adding your own error statements in your code gives you more information than a cryptic ValueError about what actually happened. If you print the traceback to your special error, it might give you still more information on your issue.

what does the error "no exception supplied" mean?

My Django app is currently throwing this error on one of my pages, does anyone know what it eans? I would supply more detail but I don't know what this error means so I'm not sure what the relevant files are and Django apps are rather large in the amount of code spread around so I'll post some code once I can get an idea of what this means. Thanks in advance for any help.
EDIT: I tried capturing the error and printing it like so:
EDIT: I've entered the code that's throwing the error
jobIDs is a dict containing all of the IDs of the records I want to modify
for i in jobIDs:
dateToRun = request.POST['dateToRun']
timeToRun = request.POST['timeToRun']
try:
if len(request.POST['dateToRun']) <= 0:
dateToRun = Job.objects.filter(id=jobIDs[i]).values()['whenToRun'].split(' ')[0]
if len(request.POST['timeToRun']) <= 0:
timeToRun = Job.objects.filter(id=jobIDs[i]).values()['whenToRun'].split(' ')[1]
except BaseException, e:
print str(e)
whenToRun = dateToRun + ' ' + timeToRun
Job.objects.filter(id=jobIDs[i]).update(whenToRun=whenToRun)
This produces a blank line of output (from the print in the except block), am I misunderstanding how to print out the error?
Are you executing a piece of code that may throw an exception? Perhaps a database query for something that does not exist? If so, you will need to wrap the block of code in a try/except clause. For example, if the exception is indeed a query for something that does not exist:
try:
#Block of code that throws exception
except Object.DoesNotExist:
#Handle error
Perhaps it's because you're using BaseException instead of just Exception? Try this:
try:
# Your code that may throw an exception
except Exception, e:
print str(e)
As per the Python Exception docs on BaseException:
exception BaseException
directly inherited by user-defined classes (for that, use Exception)The base class for all built-in exceptions. It is not meant to be directly inherited by user-defined classes (for that, use Exception).

Failed to write to file but generates no Error

I'm trying to write to a file but it's not working. I've gone through step-by-step with the debugger (it goes to the write command but when I open the file it's empty).
My question is either: "How do I see what the error is so I can debug?", "What can go wrong when trying to write to a file that would cause it to behave this way?".
sqlScript = open('script-file.sql', 'a')
try:
sqlScript.write(sqlLine)
except IOError as (errno, strerror):
print "I/O error({0}): {1}".format(errno, strerror)
This should be simple but I can't seem to find an answer. Also, I apologize in advance as English is a second language.
Edit: I put a print statement just before and the string is not empty.
Edit2: I'm using python 2.6 if that factors in somehow.
Edit 3: I've found a "solution" to my error. I decided to try and run my script using IDLE instead of PyCharm and it works like a charm (pun intended). I have no clue why, but there it is. Any reason why that would happen?!
Building on Chris Morris' answer, maybe do something like this:
try:
sqlScript.write(sqlLine)
except Exception as e:
print type(e)
print str(e)
This will catch any Exception thrown (provided it's a subclass of Exception, of course) and tell you the type and the error message.
Also, it's possible to define multiple except: cases for different possible exceptions, so maybe try doing that for each exception that might be potentially thrown/raised.
The following code allows you to see what exception it is that is being thrown, and see a trace of where it originated from.
try:
sqlScript.write(sqlLine)
except:
print "Unexpected error:", sys.exc_info()[0]
raise
See http://docs.python.org/tutorial/errors.html for more info.
You have to put your cursor at the beginning of the file. You can do that with seek method:
myScript.seek(0)
See this answer: https://stackoverflow.com/a/2949648/2119117
If no exception is being tossed, I'd suspect the string variable 'sqlLine' is empty.
Did you print it before the write statement?
Are the keywords in the script in lowercase? The same thing happened to me in another db and I solved it by changing words to UPPERCASE.
Your current working directory isn't what you expect it to be and it's successfully writing to some script-file.sql in another directory. Try printing os.getcwd() and make sure it's what you expect, and look in that directory.
It happened on my linux environment but work on windows try
sqlScript = open('script-file.sql', 'a', buffering=False)
or
sqlScript = open('script-file.sql', 'a', 0)

Categories

Resources