I've tried two different versions of the same function:
def position_of(self, table_name, column_name):
positions = self.heading_positions()
position = positions['{t}.{c}'.format(t=table_name, c=column_name)]
return position
-
def position_of(self, table_name, column_name):
positions = self.heading_positions()
try:
position = positions['{t}.{c}'.format(t=table_name, c=column_name)]
except KeyError:
raise RuntimeError('No heading found for {t}.{c} in import profile "{ip}"'.format(t=table_name, c=column_name, ip=self))
return position
With the first version, I get the following error, which is fine:
Traceback (most recent call last):
File "./import.py", line 15, in <module>
g.process()
File "/home/jason/projects/mcifdjango/mcif/models/generic_import.py", line 39, in process
row.process()
File "/home/jason/projects/mcifdjango/mcif/models/csv_row.py", line 18, in process
self.save()
File "/home/jason/projects/mcifdjango/mcif/models/csv_row.py", line 26, in save
self.output("Phone: " + self.value('customer', 'phone'));
File "/home/jason/projects/mcifdjango/mcif/models/csv_row.py", line 60, in value
print self.generic_import.import_profile.position_of(table_name, column_name)
File "/home/jason/projects/mcifdjango/mcif/models/import_profile.py", line 22, in position_of
position = positions['{t}.{c}'.format(t=table_name, c=column_name)]
KeyError: 'customer.phone'
But the second version - the one that has the more informative error description - fails silently. Why is this?
The second version of position_of works fine for me. I have turned it into a minimal complete program as follows:
class Test(object):
def heading_positions(self):
return {}
def position_of(self, table_name, column_name):
positions = self.heading_positions()
try:
position = positions['{t}.{c}'.format(t=table_name, c=column_name)]
except KeyError:
raise RuntimeError('No heading found for {t}.{c} in import profile "{ip}"'.format(t=table_name, c=column_name, ip=self))
return position
a = Test()
a.position_of('customer', 'phone')
When I run this (using Python 2.6.6 on MacOS X) I get the following error message as expected:
Traceback (most recent call last):
File "./a.py", line 17, in <module>
a.position_of('customer', 'phone')
File "./a.py", line 13, in position_of
raise RuntimeError('No heading found for {t}.{c} in import profile "{ip}"'.format(t=table_name, c=column_name, ip=self))
RuntimeError: No heading found for customer.phone in import profile "<__main__.Test object at 0x100426ad0>"
This shows that catching the KeyError and turning it into a RuntimeError works fine. Does this example work for you? As Sven already writes, a possible explanation would be if you catch RuntimeError but not KeyError somewhere in the call chain.
Related
I want to print an error's line number and error message in a nicely displayed way. The follow is my code, which uses linecache:
import linecache
def func():
if xx == 1:
print('ok')
try:
func()
except:
exc_type, exc_obj, tb = sys.exc_info()
f = tb.tb_frame
lineno = tb.tb_lineno
filename = f.f_code.co_filename
linecache.checkcache(filename)
line = linecache.getline(filename, lineno, f.f_globals)
print_('ERROR - (LINE {} "{}"): {}'.format(lineno, line.strip(), exc_obj))
However, this only gives where the func() is called:
ERROR - (LINE 8 ""): name 'xx' is not defined
Is there a way to print the line number where the error actually occured, which should be Line 4? Or even better, can I print Line 8 and then trace back to line 4? For example, if I do not use try - except, the code:
def func():
if xx == 1:
print('ok')
func()
will give me the following error message, which is much better to locate the error:
File "<input>", line 5, in <module>
File "<input>", line 2, in func
NameError: name 'xx' is not defined. Did you mean: 'xxx'?
You can use traceback and sys modules to get advanced traceback output like you are wishing for.
Here is an example:
import traceback
import sys
def func():
zeroDivide = 1 / 0
try:
func()
except Exception:
print(traceback.format_exc()) # This line is for getting traceback.
print(sys.exc_info()[2]) # This line is getting for the error type.
Output will be:
Traceback (most recent call last):
File "b:\abc\1234\pppp\main.py", line 10, in <module>
func()
File "b:\abc\1234\pppp\main.py", line 7, in func
zeroDivide = 1 / 0
ZeroDivisionError: division by zero
You can use the traceback module to get the line number of the error,
import traceback
def function():
try:
# code
except:
tb_list = traceback.extract_tb(sys.exc_info()[2])
line_number = tb_list[-1][1]
print("An error occurred on line:", line_number)
You can use the traceback.extract_tb() function. This function returns a list of traceback objects, each of which contain information about the stack trace. The last element of this list, tb_list[-1], holds information about the line where the exception occurred. To access the line number, you can use the second element of this tuple, tb_list[-1][1]. This value can then be printed using the print() function.
To get the line number as an int you can get the traceback as a list from traceback.extract_tb(). Looking at the last item gives you the line where the exception was raised:
#soPrintLineOfError2
import sys
import traceback
def func():
if xx == 1:
print('ok')
try:
func()
except Exception as e:
tb = sys.exc_info()[2]
ss = traceback.extract_tb(tb)
ss1 = ss[-1]
print(ss1.line)
print(ss1.lineno)
Output:
if xx == 1:
6
I am assigning the stack trace variable traceback.format_exc() to a list as below ,strange thing I notice is after appending ,all the single quotes(') get escaped (\') as can be seen from the output below.
I looked on google #https://github.com/behave/behave/issues/336 and tried to assign (traceback.format_exc(), sys.getfilesystemencoding() which didn't work either,am very curious why is this happening and how to fix this?
import traceback
clonedRadarsdetailslist = []
clonedRadardetails = {}
try:
#raise
(updateproblemoutput,updateproblempassfail) = r.UpdateProblem(problemID=newRadarID, componentName=componentName, componentVersion=componentVersion,assigneeID=assignee,state=state,substate=substate,milestone=milestone, category=category,priority=priority,resolution=re_solution )
except:
clonedRadardetails['updatedFailedReason'] = traceback.format_exc()
clonedRadarsdetailslist.append(clonedRadardetails)
print clonedRadarsdetailslist
OUTPUT:-
['{\'clonedRadar\': 40171867, \'clonedStatus\': \'PASS\', \'clonedRadarFinalStatus\': \'PASS\', \'updatedFailedReason\': \'Traceback (most recent call last):\\n File "./cloneradar.py", line 174, in clone\\n (updatetitleoutput,updatetitlepassfail) = r.UpdateProble(problemID=newRadarID,title=title )\\nAttributeError: \\\'RadarWS\\\' object has no attribute \\\'UpdateProble\\\'\\n\', \'clonedRadarFinalStatusReason\': \'N/A\', \'updateStatus\': \'FAIL\', \'clonedStatusfailReason\': \'N/A\'}', '{\'clonedRadar\': 40171867, \'clonedStatus\': \'PASS\', \'clonedRadarFinalStatus\': \'PASS\', \'updatedFailedReason\': \'Traceback (most recent call last):\\n File "./cloneradar.py", line 174, in clone\\n (updatetitleoutput,updatetitlepassfail) = r.UpdateProble(problemID=newRadarID,title=title )\\nAttributeError: \\\'RadarWS\\\' object has no attribute \\\'UpdateProble\\\'\\n\', \'clonedRadarFinalStatusReason\': \'N/A\', \'updateStatus\': \'FAIL\', \'clonedStatusfailReason\': \'N/A\'}']
lambda from getattr getting called with "connection" as a keyword argument? Am I misusing the code or is there a bug?
Code and traceback: https://github.com/bigcommerce/bigcommerce-api-python/issues/32
#!/usr/bin/env python2
import bigcommerce
import bigcommerce.api
BIG_URL = 'store-45eg5.mybigcommerce.com'
BIG_USER = 'henry'
BIG_KEY = '10f0f4f371f7953c4d7d7809b62463281f15c829'
api = bigcommerce.api.BigcommerceApi(host=BIG_URL, basic_auth=(BIG_USER, BIG_KEY))
def get_category_id(name):
get_request = api.Categories.get(name)
try:
cat_list = api.Categories.all(name=name)
if cat_list:
return cat_list[0]['id']
else:
return None
except:
return None
def create_category(name):
rp = api.Categories.create(name)
if rp.status == 201:
return rp.json()['id']
else:
return get_category_id(name)
create_category('anothertestingcat')
Gives this traceback:
Traceback (most recent call last):
File "./bigcommerceimporter.py", line 50, in
create_category('anothertestingcat')
File "./bigcommerceimporter.py", line 44, in create_category
rp = api.Categories.create(name)
File "/home/henry/big_test_zone/local/lib/python2.7/site-packages/bigcommerce/api.py", line 57, in
return lambda args, *kwargs: (getattr(self.resource_class, item))(args, connection=self.connection, *kwargs)
TypeError: create() got multiple values for keyword argument 'connection'
Line in api.py that the traceback refers to: https://github.com/bigcommerce/bigcommerce-api-python/blob/master/bigcommerce/api.py#L57
According to the examples, create should be used like this:
api.Categories.create(name = 'anothertestingcat')
Note: You should generate a new API KEY, since you published the current one in this question.
Anyone come across this before?
import boto
conn = boto.dynamodb.connect_to_region('eu-west-1', aws_access_key_id=aws_key, aws_secret_access_key=aws_secret)
table = conn.get_table('TweetSample')
print table.scan(limit=1)
error:
Traceback (most recent call last):
File "test.py", line 9, in <module>
print table.scan(limit=1)
File "table.py", line 518, in scan
return self.layer2.scan(self, *args, **kw)
TypeError: scan() got an unexpected keyword argument 'limit'
[Finished in 0.4s with exit code 1]
I don't even know...
According to the documentation, scan method of boto.dynamodb.table.Table (which is returned by boto.dynamodb.layer2.Layer2.get_table) does not accepts limit, but max_results.
And the result is a generator. So, if you want to print it you should iterate it:
import boto.dynamodb
conn = boto.dynamodb.connect_to_region(
'eu-west-1',
aws_access_key_id=aws_key,
aws_secret_access_key=aws_secret)
table = conn.get_table('TweetSample')
for row in table.scan(max_results=1):
print row
or convert it to a sequence:
print list(table.scan(max_results=1))
I'm trying to implement an assert function. How can I get the text of the failing condition into the error message? If I have to parse it from the backtrace, can I portably rely on anything about the format of frames?
AssertionError is just like any other exception in python, and assert is a simple statement that is equivalent to
if __debug__:
if not expression: raise AssertionError
or
if __debug__:
if not expression1: raise AssertionError(expression2)
so you can add a second parameter to your assertion to have additional output
from sys import exc_info
from traceback import print_exception
# assertions are simply exceptions in Python
try:
assert False, "assert was false"
except AssertionError:
print_exception(*exc_info())
outputs
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
AssertionError: assert was false
If you're sure the expression to test is secure you could do something like this:
File my_assert.py:
import sys
def my_assert(condition):
caller = sys._getframe(1)
if not eval(condition, caller.f_globals, caller.f_locals):
raise AssertionError(repr(condition) + " on line " +
str(caller.f_lineno) + ' in ' +
caller.f_code.co_name)
File test_my_assert.py:
from my_assert import my_assert
global_var = 42
def test():
local_var = 17
my_assert('local_var*2 < global_var') # OK
my_assert('local_var > global_var')
test()
Output:
Traceback (most recent call last):
File "test_my_assert.py", line 10, in <module>
test()
File "test_my_assert.py", line 8, in test
my_assert('local_var > global_var')
File "my_assert.py", line 8, in my_assert
caller.f_code.co_name)
AssertionError: 'local_var > global_var' on line 8 in test
My very hackish solution:
def my_assert(condition):
if not eval(condition):
# error stuff
Then use it by placing the condition in quotation marks. It is then a string that can be printed in the error message.
Or, if you want it to actually raise an AssertionError:
def my_assert(condition):
if not eval(condition):
raise AssertionError(condition)