Exception message best practices [closed] - python

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I've written a small production-level Flask application in Python with standard exception handling. Most of the time I'm just logging the exception message and it looks like this
try:
#Do something
except Exception, e:
logger.error('Exception in LoadValidationDocs in main.py : %s' % str(e.args))
return None
I was wondering if I should keep all such error messages in a separate strings.py file like
standard_exception_message = 'Exception in %s in %s, Exception Args : %s'
and get function and module name at run time like
import inspect
function_name = inspect.stack()[0][3]
file_name = os.path.basename(__file__)
logger.error(strings. standard_exception_message % (function_name, file_name, str(e.args)))
I just want to know whether it's necessary to do that and is it even the correct way of doing it considering my current scenario.

You can use logging.exception instead of logging.error. It will take care of looking for the function, module name etc. for you in a formatted way:
import logging
try:
# Do something that will fail
x = 1 / 0
except Exception as e:
logging.exception("This is my message when an error happens here.")
It gives:
ERROR:root:This is my message when an error happens here.
Traceback (most recent call last):
File "question39724934.py", line 5, in compute
x = 1 / 0
ZeroDivisionError: division by zero

Related

traceback not full when passing to next fucntion [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
Basically I have something like this:
import traceback
def function1():
try:
temp = None
temp = int(temp)
except:
pass
Which obviously rises error (due to casting NoneType to int), then there is a second method that is called only if previous one had error:
def function2():
# do something
traceback.print_exc()
Though it doesn't print full traceback as it would do if invoked in the except clause, it just says:
NoneType: None
Where does this change come from? And is there any way to still print a full stack trace?
If you call like this, the error context, the traceback does not longer exists as you went away from it
function1()
function2()
You need to call function2 from the except block, to keep track of the traceback
import traceback
def function1():
try:
temp = None
temp = int(temp)
except:
function2()
def function2():
traceback.print_exc()
if __name__ == '__main__':
function1()
Giving
Traceback (most recent call last):
File "C:\Users\...\test_4.py", line 7, in function1
temp = int(temp)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

Python unit test - NameError: name 'upper' is not defined [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
Using Python 3.x. When running the test case for the following code, I get the error - NameError: name 'upper' is not defined. I am attaching the file to test, the File_P_third file where is the code, and the unit test file test_upper.
File File_P_third:
def upper_text(text):
return text.upper()
File test_upper:
import unittest
import File_P_third
class TestUpper(unittest.TestCase):
"""docstring for ClassName"""
def test_one_word(self):
text = 'hello!'
result = upper.upper_text(text)
self.assertEqual(result, 'HELLO!')
if __name__ == '__main__':
unittest.main()
My cmd`s exit text:
D:\Дохуя программист\Projects>python test_upper.py
E
======================================================================
ERROR: test_one_word (__main__.TestUpper)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_upper.py", line 9, in test_one_word
result = upper.upper_text(text)
NameError: name 'upper' is not defined
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
All files is in one directory and I still cant understand why is doesnt work. Can`t search the same problem in internet((
If you're trying to transform 'hello' to upper case, the function to do so in python is string.upper()
i takes no parameter see below:
test='hello'
up=test.upper()
print(up)
# prints HELLO
Replace import File_P_third with from File_P_third import upper_text. Call your function this way result = upper_text(text). Also make sure, both files File_P_third.py and test_upper.py are in the same directory.
Below you'll find the complete code for your file File_P_third.py:
import unittest
from File_P_third import upper_text
class TestUpper(unittest.TestCase):
"""docstring for ClassName"""
def test_one_word(self):
text = 'hello!'
result = upper_text(text)
self.assertEqual(result, 'HELLO!')
if __name__ == '__main__':
unittest.main()

Formatting Stack Overflow questions using Python

I'm working on a script that will run another script and automatically generate a formatted Stack Overflow question based on the problem the script is having. I'd like to be able to provide accurate code samples and tracebacks while avoiding all the copying and pasting. Here's what I have so far:
# script.py
# usage: python3 script.py > stack_overflow_question.txt
from os.path import basename
from traceback import format_exc
def stack_overflow_question_generator(q_params):
"takes a source script & descriptions and returns a Stack Overflow question"
# get the code from the source script & pad each line with spaces
with open(q_params['source']) as f:
source = f.readlines()
code = ''.join(4 * ' ' + i for i in source)
# run the source script and get the traceback object
try:
trace_obj = None
try:
source_module = q_params['source'][:q_params['source'].index('.')]
__import__(source_module)
except Exception as e:
raise RuntimeError from e
except RuntimeError:
trace_obj = format_exc()
# raise a warning if the source script doesn't raise an error
if not trace_obj:
no_error_message = 'No exception raised by ' + q_params['source']
raise UserWarning(no_error_message)
# break the trace up into lines
trace_lines = trace_obj.split('\n')
# find the first line in the trace from the source and target it & its index
for i, t in enumerate(trace_lines):
if q_params['source'] in t:
target_line = t
index_one = i + 1
break
# find the first line of the outer trace and target its index
break_trace = ' '.join(['The above exception was the direct',
'cause of the following exception:'])
index_two = trace_lines.index(break_trace) - 1
# find the source script name in the target line & rebuild it with that name
quotes_index = [i for i, x in enumerate(target_line) if x == '"'][:2]
source_name = basename(target_line[quotes_index[0] + 1:quotes_index[1]])
filename = ''.join([' File "', source_name, target_line[quotes_index[1]:]])
# format the source traceback as a string & pad each line with spaces
trace = '\n'.join(4 * ' ' + i
for i in [trace_lines[0],
filename] + trace_lines[index_one:index_two])
# build and return the question formatted as a string
return '\n'.join([q_params['issue'], code, q_params['error'], trace,
q_params['request']])
# Example: set source script & other question params (issue, error, request):
question_params = {
'source': 'script.py',
'issue': ' '.join(['I\'m working on a script that will run another script',
'and automatically generate a formatted Stack Overflow',
'question based on the problem the script is having.',
'I\'d like to be able to provide accurate code samples',
'and tracebacks while avoiding all the copying and',
'pasting. Here\'s what I have so far:\n']),
'error': ' '.join(['However, when the source script doesn\'t actually',
'raise an exception, the question-generator script',
'can\'t really format the question appropriately and',
'just raises a warning:\n']),
'request': ' '.join(['Is there a better way for this script to generate',
'questions when the original script doesn\'t raise',
'any errors but still has some issue? I\'d also love',
'to see any implementations that accomplish the task',
'more efficiently or that improve the quality of the',
'question. (Also, apologies if this question is',
'better suited to stack overflow meta or code review;',
'I figured it made more sense here since I\'m trying',
'to build a tool in python for formatting output from',
'a python script.)'])
}
# Generate & print formatted SO question
print(stack_overflow_question_generator(question_params))
However, when the source script doesn't actually raise an exception, the question-generator script can't really format the question appropriately and just raises a warning:
Traceback (most recent call last):
File "script.py", line 19, in stack_overflow_question_generator
__import__(source_module)
File "/Users/alecrasmussen/script.py", line 86, in <module>
print(stack_overflow_question_generator(question_params))
File "/Users/alecrasmussen/script.py", line 28, in stack_overflow_question_generator
raise UserWarning(no_error_message)
UserWarning: No exception raised by script.py
Is there a better way for this script to generate questions when the original script doesn't raise any errors but still has some issue? I'd also love to see any implementations that accomplish the task more efficiently or that improve the quality of the question. (Also, apologies if this question is better suited to stack overflow meta or code review; I figured it made more sense here since I'm trying to build a tool in python for formatting output from a python script.)

proper way to get nice string from exception

I want to generate a one-line string from an Exception which tells me what happened where (don't need a full backtrace). The following information would be nice:
filename / linenumber
exception type
exception description (what you get from str(e))
nice to have: function/method/class
Currently I do the following:
import os
...
try:
os.nonexisting()
except Exception as e:
t = e.__traceback__
tbf = e.__traceback__.tb_frame
print('%s:%d: %s in %s(): "%s" ' %
os.path.basename(tbf.f_code.co_filename),
t.tb_lineno,
e.__class__.__name__,
tbf.f_code.co_name, e))
which gives me:
foo.py:203: AttributeError in foo(): "'module' object has no attribute 'nonexisting'"
Is there a more elegant way to print out the details given in this example? I'm thinking about s.th. like
print(e.format('%f: %l: %t %F: "%w"'))
I'd like to avoid importing extra modules except there is one exactly for this purpose.
I think traceback.format_exception_only does exactly what you want.
try:
os.nonexisting()
except Exception as e:
print(traceback.format_exception_only(e.__class__, e))

Compile Python Error [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a Code from Python 2.4 and Want to Compile this code on Python 2.6 but I see this Error:
>>> py_compile.compile("Model.py")
SyntaxError: ('invalid syntax', ('pcbModel.py', 73, 19, ' msg = "%s: %s. The error occurred generating \'%s\'." % (sys.exc_type, sys.exc_value, bName)\n'))
and code is:
try:
pcb.Create(self.skipMeshing, analysisType = self.analysisType)
msg = "%s: %s. The error occurred generating '%s'." % (sys.exc_type, sys.exc_value, bName)
raise Exception, msg
continue
self.deactivate(bName)
how solve it?
It looks like you have a try clause, with no corresponding except. also, raise type, args form is deprecated, use raise type(args). also, sys.exc_type and friends are not thread safe. The syntactically correct version is:
# DON'T DO THIS, SEE BELOW
try:
pcb.Create(self.skipMeshing, analysisType = self.analysisType)
except Exception as e:
msg = "%s: %s. The error occurred generating '%s'." % (type(e), e, bName)
raise Exception(msg)
However, It appears as though you are trying to "catch" the exception, compute some sort of error message and raise an exception. exceptions already do that. the idomatic version of the above is actually,
pcb.Create(self.skipMeshing, analysisType = self.analysisType)
with no try, no except and no raise. If pcb.Create() raises an exception, it has already raised an exception, you don't need to raise another one.

Categories

Resources