Any way to save a traceback object in Python - 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.

Related

Is there a simple way to comment out or diable a python try statement without re-indenting

Problem:
Sometimes it is nice to be able to remove or apply a try statement temporarily. Is there a convenient way to disable the try statement without re-indenting?
For example, if there was a python block statement equivalent called "goForIt:" one could edit the word "try:" to "goForIt:" and it would just execute the block as though it were not wrapped in a "try" and ignore the "except" line too.
The problem I'm trying to solve is that while I want the try statement in production I want to be able to remove it temporarily while debugging to see the error traceback rather than have it trap and process the exception.
Currently I work around this by commenting out the "try" then re-indent the code in the block. Then comment out the entire "except" block. This seems clumsy.
Instead of removing the try, you could make the except re-raise the exception:
try:
raise ValueError('whoops')
except ValueError as e:
raise # <-- just put this here
print('caught')
This will raise the error, just as if it were not caught:
ValueError Traceback (most recent call last)
<ipython-input-146-a6be6779c161> in <module>
1 try:
----> 2 raise ValueError('whoops')
3 except ValueError as e:
4 raise
5 print('caught')
ValueError: whoops
I do not believe there is a way to fix this.
Is it adequate to catch the exception, print it out and, if wanted, end the program?
try:
# code
except Exception as e:
print(e)
# end program if wanted
If you want a none code solution you need to use an IDE or a good text editor.
I am using Visual Studio code where I can indent with a keyboard shortcut (Ctrl + ` in my case)
(This is not my answer, but the answer from Alani's comment. If credits, find the original comment under the question.)
The solution is good because it allows global replacement:
try: --> if 1: # try:
except --> if 0: # except
The 2nd one is a little unsure. Exact and full word match should be used, or replace twice (for except<space> and except:). Or you can fix error fast by hand if there is any.
The replacement back is sure.
I need now such solution to debug error in strawberry which is only printed. So I think I need deactivate all try/except structures in 3 libraries (strawberry + 2 libs for django).

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))

How to know which line gives error in python?

I am new to Python so please excuse my rudimentary question.
When I get an error I can usually figure out what line caused the error, but sometimes from the error message itself I can't decide which line is responsible. So I add some messages between the lines to track the issue. Is there any more effective solution to that?
I am running my codes form ArcGIS toolbox script and I am not sure if I can trace the errors from there.
I always use print statements (okay, function in Py3). It's the most standard way. Just use it to track where are you now in your program, and what are you doing.
However, if your application processes a large data, or if it's a large application, print statements may be not enough. Sometimes, you'll need try and except statements, just to narrow the search of the error.
More on error handling? Here!
This may also be useful.
If youre trying to do this with a excepted error do this:
import traceback
import sys
try:
raise Exception("foo")
except:
for frame in traceback.extract_tb(sys.exc_info()[2]):
fname,lineno,fn,text = frame
print "Error in %s on line %d" % (fname, lineno)
otherwise just read the traceback

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