When I execute logger.info(traceback.print_exc())
the trace gets on console rather than in the log file
I have logger.propagate = False also still the same issue
print_exc prints the stack trace to stderr.
Just use the exc_info=1 argument and it will automaticaly include the exception.
logging.exception("Exception") #or
logging.error("exception ",exc_info=1) #or
logging.info("Exception has occured" ,exc_info=1)
I am using python 2.7 and sadly exc_info=1 never worked for me so I had to use this:
import traceback
...
log.debug(traceback.format_exc())
Related
name = input('name? ')
if len(name) == 0:
print('error.\n')
raise SystemExit
I receive an error when using python 3.3.2 (which is the version is school sadly) but it works fine on other versions e.g. 2.7.10 and 3.5
This is the error
Looking at the screenshot I can see Python prompt at the bottom:
This means the script is run in an interactive session (IDLE on Windows I guess). I haven't found any documentation, but other users have discovered that raising SystemExit in an interactive session does print the traceback.
So you should check and ensure that you are not launching the script in an interactive session.
Old answer:
Looks like it's a bug (or a particularity) in Python 3.3.2. According to this blog post:
If nothing catches the exception, then the python interpreter catches
it at the end, does not print a stack trace, and then calls exit.
I tried to raise SystemExit('asd') and the program just printed asd, so looks like it's true.
Either upgrade Python or try os._exit(1).
Not sure if this is what you want, but if you wanna exit use this:
import sys
name = raw_input('name? ')
if len(name) == 0:
print('error.\n')
sys.exit()
This exits the interpreter by raising SystemExit.
Why don't you use sys.exit()?
sys.exit([arg])
Exit from Python. This is implemented by raising the SystemExit exception, so cleanup actions specified by finally clauses of try statements are honored, and it is possible to intercept the exit attempt at an outer level.
You probably have an handler set for excepthook:
https://docs.python.org/3/library/sys.html#sys.excepthook
You should be able to reset it by doing
sys.excepthook = sys.__excepthook__
Nevermind, the hook works correctly for BaseException, but weirdly enough not for SystemExit (which is a subclass of BaseException).
You're probably executing your program with
python3 -i whatever.py
This gives me the same behavior you witnessed:
dario#feynman ~> python3 -i /tmp/a.py
Traceback (most recent call last):
File "/tmp/a.py", line 11, in <module>
raise SystemExit()
SystemExit
>>>
Note the >>> at the end.
Just remove the -i flag, from whatever is executing your program
Alternatively, it's bad practice, but you can also use os._exit(1)
I'm using Twister to build a server. I am also maintaining a server error log. The issue is that if I let an exception run all the way up the stack, it'll crash the current connection and disconnect the user, so obviously I attach a bare except to grab everything else.
Once I've caught something, is there a way to get the traceback as a string so that I can store it somewhere/print it myself without raising it and letting Python print it for me once the program crashes?
The traceback module contains some helper functions for printing and inspecting the traceback (for exameble, traceback.print_tb ) - but the important thing is that the traceback information itself is stored in a "interpreter global" variable - sys.exc_traceback, on the module sys.
Quoting from:
http://docs.python.org/reference/compound_stmts.html#try
Before an except clause’s suite is executed, details about the
exception are assigned to three variables in the sys module:
sys.exc_type receives the object identifying the exception;
sys.exc_value receives the exception’s parameter; sys.exc_traceback
receives a traceback object...
You can pass the sys.exc_traceback object as a parameter to traceback.print_tb to have the traceback printed to stdout within the except clause.
Using the logging module, you could log the traceback to a file:
import logging
logging.basicConfig(level = logging.DEBUG, filename = logfile)
logger = logging.getLogger(__name__)
try:
1/0
except ZeroDivisionError as err:
logger.exception(err)
Try this:
import traceback, sys
try:
# Do something that might raise an exception
open("/does not exist",'rb')
except:
traceback.print_exc( file=sys.stderr )
# Or
traceback.print_exc( file=your_open_log_file )
That should do the trick and print full stack traces too.
Yep, there's a module for that. The traceback module contains functions to print or format exception information, or to return the raw stack frames so you can do whatever you want with them.
For a reasonably sophisticated application, though, I would actually recommend using the logging system instead of plain old traceback functions. In particular the method logging.Logger.exception will write information about the exception to whatever logging destination you (or your software's user) has configured. The default formatter will just print out a traceback, as Python would on the console, but you can customize the display of exceptions in your log by creating a Formatter and overriding the format_exception method. Your overridden method is the place to call traceback functions if you need them to format the exception output.
I am running an IronPython script inside a c# application, i am catching exceptions within the script and i wish to find out the script line at which the exception is thrown. This has to be done while the script is running ie. i do not wish the script to terminate in order to print the exception.
Is this even possible?
If inspect is working as expected under IronPython (not really sure) this could do the trick:
import inspect
filename, linenum, funcname = inspect.getframeinfo(inspect.currentframe())[:3]
print linenum
Edit: alternate solution:
import sys
frame = sys._getframe()
print frame.f_lineno
Haven't tried this on ironpython but:
import traceback
try:
# something that raises exception
except YourException, _:
traceback.print_exc()
This should show you the stack trace of the place where the exception was raised. You can also do other stuff than just print, like print to string, or get the stack frames.
The traceback module documentation will tell you more.
I create a file called foo_module.py containing the following code:
import shelve, whichdb, os
from foo_package.g import g
g.shelf = shelve.open("foo_path")
g.shelf.close()
print whichdb.whichdb("foo_path") # => dbhash
os.remove("foo_path")
Next to that file I create a directory called foo_package than contains an empty __init__.py file and a file called g.py that just contains:
class g:
pass
Now when I run foo_module.py I get a weird error message:
Exception TypeError: "'NoneType' object is not callable" in ignored
But then, if I rename the directory from foo_package to foo, and change the import line in foo_module.py, I don't get any error. Wtf is going on here?
Running Python 2.6.4 on WinXP.
I think you've hit a minor bug in 2.6.4's code related to the cleanup at end of program. If you run python -v you can see exactly at what point of the cleanup the error comes:
# cleanup[1] foo_package.g
Exception TypeError: "'NoneType' object is not callable" in ignored
Python sets references to None during the cleanup at the end of program, and it looks like it's getting confused about the status of g.shelf. As a workaround you could set g.shelf = None after the close. I would also recommend opening a bug in Python's bug tracker!
After days of hair loss, I finally had success using an atexit function:
import atexit
...
cache = shelve.open(path)
atexit.register(cache.close)
It's most appropriate to register right after opening. This works with multiple concurrent shelves.
(python 2.6.5 on lucid)
This is indeed a Python bug, and I've posted a patch to the tracker issue you opened (thanks for doing that).
The problem is that shelve's del method calls its close method, but if the shelve module has already been through cleanup, the close method fails with the message you see.
You can avoid the message in your code by adding 'del g.shelf' after g.shelf.close. As long as g.shelf is the only reference to the shelf, this will result in CPython calling the shelve's del method right away, before the interpreter cleanup phase, and thus avoid the error message.
It seems to be an exception in a shutdown function registered by the shelve module. The "ignored" part is from the shutdown system, and might get its wording improved sometime, per Issue 6294. I'm still hoping for an answer on how to eliminate the exception itself, though...
for me a simple shelve.close() on an unclosed one did the job.
shelve.open('somefile') returns a "persistent dictionary for reading and writing" object which i used throughout the app's runtime.
when I terminated the app I received the "TypeError" Exception as mentioned.
I plased a 'close()' call in my termination sequence and that seemed to fix the problem.
e.g.
shelveObj = shelve.open('fileName')
...
shelveObj.close()
OverByThere commented on Jul 17, 2018
This seems to be fixable.
In short open /usr/lib/python3.5/weakref.py and change line 109 to:
def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref):
And line 117 to:
_atomic_removal(d, wr.key)
Note you need to do this with spaces, not tabs as this will cause other errors.
See the title of this question. I want to play with the exception raised in the last command. _ didn't help me. Is there anything like that?
Do this:
import sys
sys.exc_info()
It will give you information about the exception. It's a tuple containing the exception type, the exception instance and a traceback object.
If your 'interactive' happens within Jupyter, check this > Jupyter magic to handle notebook exceptions
It is just beautiful.
If you want to add a sound > Jupyter / Colab : Play sound with any error in any cell + Play sound after completing long running cells