Retrieve stack trace in django Middleware - django

How can I get the stack trace when something fails on the server side in the django middleware?
Here is what I've tried that only gives me the message, not the full stack.
class MonitorMiddleware(object):
def process_exception(self, request, exception):
self.error = exception.message

Answer to "retrieve the error stack trace to save to the database" from comment:
https://docs.python.org/3/library/traceback.html
Use the methods of traceback to convert the trace of the exception into a string which you can then store in the database.
Also on the above page:
New in version 3.5.
StackSummary objects represent a call stack ready for formatting.
The short short example with an exception object:
>>> an_error = IndexError('tuple index out of range')
>>> traceback.print_exception(type(an_error), an_error, an_error.__traceback__)
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
IndexError: list index out of range
See also Extract traceback info from an exception object:
You don't need to re-raise the exception, though, the traceback is in the __traceback__ attribute.

Related

Why isdigit is working but isdecimal is not for a simple age code

This is the part of code I am talking about:
while True:
print 'What is your age(only numeric):'
age = raw_input()
if age.isdigit():
break
print 'Please try again. We take only numeric value.'
When I replace isdigit with isdecimal, I get this error no matter what value i enter.
Traceback (most recent call last):
File "test.py", line 4, in <module>
if age.isdecimal():
AttributeError: 'str' object has no attribute 'isdecimal'
Although it runs fine with isdigit.
Also, when I replace raw_input with input, it give this error.
Traceback (most recent call last):
File "test.py", line 4, in <module>
if age.isdigit():
AttributeError: 'int' object has no attribute 'isdigit'
Am I doing something wrong which I am not able to catch? I am new to python and did my research about isdigit, is decimal, input and raw_input before putting down question here. It may be very minute error but I am not sure what is it.
For the first part:
In Python 2, isdecimal is a method of the unicode class, not of str (i.e. bytes). Hence:
>>> '3.2'.isdecimal()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'isdecimal'
>>> u'3.2'.isdecimal()
For the second part, input tries to guess what kind of input it gets, and will properly cast "1" into an int, while raw_input will always return the raw string. Since isdigit is a method defined in the str class, you get the error.

python caught exception stacktrace vs uncaught exception stacktrace

I have a try except block in my code where I am expecting a django.core.exceptions.ValidationError kind of excepption, catching it and logging it. I have tried various ways to log the exception, from simple logger.excepption to all the functions from traceback library. following is the stacktrace I get everytime:
Traceback (most recent call last):
File "/home/belong/work/code/hulk/hulk/commons/decorators.py", line 48, in func_wrapper
func(*args, **kwargs)
File "/home/belong/work/code/hulk/hulk/job/views.py", line 211, in create
raise DjangoCoreValidationError('test')
ValidationError: [u'test']
Whereas, if I dont catch the exception at all, python logs it as an uncaught exception and I get the following stacktrace:
2019-07-09 06:09:56,445 ERROR MainProcess [hulk.commons.exceptions.handlers: 35] [oid: 706a0f00ea9d476291ba118e61576622] [strail: hulk] [aid: ] Uncaught exception
Traceback (most recent call last):
File "/home/belong/work/code/hulk/venv/local/lib/python2.7/site-packages/rest_framework/views.py", line 480, in dispatch
response = handler(request, *args, **kwargs)
File "/home/belong/work/code/hulk/hulk/job/views.py", line 211, in create
raise DjangoCoreValidationError('test')
ValidationError: [u'test']
Why are these 2 different? Is there any way I can get the same stacktrace as the uncaught one while catching and logging the same exception?

Python calling documentation of defined function

I am a newbie to python. Just try to get the comments defined in function using doc but getting the error.
Here's my code:
def nam(i):
"""passing the name to
a function"""
print('hello '+i+' good mornin')
And here's the error:
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
print(nam._doc_)
AttributeError: 'function' object has no attribute '_doc_'
Replace _doc_ (single underline on each side) with __doc__ (double underlines)
To illustrate, let's define your function and display the documentation:
>>> def nam(i):
... """passing the name to
... a function"""
... print('hello '+i+' good mornin')
...
>>> nam.__doc__
'passing the name to\n a function'
The method above works. The method below, however, fails:
>>> nam._doc_
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute '_doc_'
The reason is that __doc__ needs two underline characters on each side, not just one.
Documentation
From the python online documentation:
docstring A string literal which appears as the first expression
in a class, function or module. While ignored when the suite is
executed, it is recognized by the compiler and put into the __doc__
attribute of the enclosing class, function or module. Since it is
available via introspection, it is the canonical place for
documentation of the object.

Formatting error reporting

I am logging all errors to a file, since there is no other way to see them properly in my case, especially in prod environment. Like this:
sys.stderr = open('py/log/my_logfile.error.log', 'a')
I am getting something similar to this:
Traceback (most recent call last):
File "my_awesome_file.py", line 50, in <module>
revision = session.Query()
AttributeError: 'Awesome' object has no attribute 'SomeSortOfAttribute'
Traceback (most recent call last):
File "my_awesome_file.py", line 50, in <module>
revision = session.Query()
AttributeError: 'Awesome' object has no attribute 'SomeSortOfAttribute'
It's two errors here (well, same error logged twice). I'd like to have if formatted a bit nicer (i.e. additional newline in between errors), and add a datetime if possible. Can I do it using this method of error logging?
After a little bit of reading Python manuals, it seems the solution is rather easy - instead of directly using file open() as a stream for stderr, I just have to use a custom stream. It's so painfully obvious it puzzles me why I didn't come up with it immediately. Well, it was Friday evening after all.
A very basic version would be:
import time
class LogStream(object):
def write(self, text):
f = open('py/log/my.custom.error.log', 'a')
f.write(time.strftime("%H:%M:%S ") + text + "\r\n")
f.close()
And then
sys.stderr = LogStream()
Result:
12:03:05 Traceback (most recent call last):
12:03:05 File "py/stuff.py", line 38, in <module>
12:03:05
12:03:05 raise Exception("just some test")
12:03:05 Exception
12:03:05 :
12:03:05 just some test
12:03:05
I might want to customize it a bit more but it's good enough already.

os.system in a loop

For each item in a list, I am modifying a file and then I want to run the python script, "ncall.py", which imports the modified file called, "new_basketparams.txt". I also want to make sure ncall.py completes its process before recalling it, but that is perhaps another topic. I am working on an ubuntu linux machine with python 2.7.
Here's the issue: My code seems to call ncall.py infinite times, stuck inside of the loop. I cannot even use a keyboard shortcut to kill the process and must close the window to kill the process. Here is my code and if anyone can help explain a solution, or guide me, that would be greatly appreciated:
import os
import re
datelist=['2014-05-16','2014-05-15','2014-05-14','2014-05-13','2014-05-12']
for date in datelist:
f=open('basketparams.txt')
g=open('new_basketparams.txt','w')
for line in f:
if "Start" in line:
line=line.split(";")
line[2]=re.sub('\d\d\d\d-\d\d-\d\d',date,line[2])
line=';'.join(line)
elif "End" in line:
line=line.split(";")
line[2]=re.sub('\d\d\d\d-\d\d-\d\d',date,line[2])
line=';'.join(line)
else:
pass
g.write(line)
os.system("python ncall.py")
Here are some diagnostics. The import MySQL error is strange because ncall works when called by itself from the terminal
'import site' failed; use -v for traceback
Traceback (most recent call last):
File "ncall.py", line 1, in <module>
import MySQLdb
ImportError: No module named MySQLdb
[]
calling ncall.py no. 1 2014-05-21 07:30:46.400011
new_basketparams.txt
Traceback (most recent call last):
File "ncall.py", line 15, in <module>
Price_Min=display.input[2]
IndexError: list index out of range
[]
calling ncall.py no. 1 2014-05-21 07:30:46.352573
new_basketparams.txt
Traceback (most recent call last):
File "ncall.py", line 15, in <module>
Price_Min=display.input[2]
IndexError: list index out of range
[]
calling ncall.py no. 1 2014-05-21 07:30:46.305043
new_basketparams.txt
Traceback (most recent call last):
File "ncall.py", line 15, in <module>
Price_Min=display.input[2]
IndexError: list index out of range
Now I am including a portion of code from ncall.py as well as display.py:
#ncall.py
import MySQLdb
import csv
import display
import time
from display import fileinput
from datetime import datetime, date, time, timedelta
import datelist
now0=datetime.now()
print fileinput
Start_Datetime='%s 14:00:00'%(datelist.date)
End_Datetime='%s 14:59:59'%(datelist.date)
Price_Min=display.input[2]
Price_Max=display.input[3]
Under=display.input[4]
#display.py
fileinput='new_basketparams.txt'
f=open(fileinput)
input=[]
for line in f:
print 'reading line in fileinput in display.py\'s loop: ', line
try:
line=line.split(';')
parameter=line[0]
Input=line[2]
x=Input.split('\r')
input.append(x[0])
except :
continue