Reputation:
I am trying to create HTML format (for sending automatic emails)from JSON data I get from an internal database, I am getting the following error for 'None' type,I want to capture 'None' type aswell?how to not throw an error even for 'None' type?
INPUT:-
{'total': 0, 'Resolution': None, 'key': u'CNSSDEBUG-151394', 'summary': u'[Lenovo][NFA344A][Win10] - [QCA6174_9377.WIN.1.0-10366-QCARMTFX86WZ-2] - Undetermined crash root cause'}
CODE:-
........
for item in jiradb :
MailBody = MailBody + "<tr>"
MailBody = MailBody + "<td>" + str(icount) + "</td>"
print item['key']
MailBody = MailBody + "<td>" + item['key'].rstrip('\n!') + "</td>"
MailBody = MailBody + "<td>" + item['summary'].rstrip('\n!') + "</td>"
MailBody = MailBody + "<td>" + item['Resolution'].rstrip('\n!') + "</td>"
icount = icount + 1
.......................
Error:-
Traceback (most recent call last):
File "sns.py", line 217, in <module>
main()
File "sns.py", line 215, in main
sendmail(meta,jiradb,total_no_crashes)
File "sns.py", line 47, in sendmail
MailBody = MailBody + "<td>" + item['Resolution'].rstrip('\n!') + "</td>"
AttributeError: 'NoneType' object has no attribute 'rstrip'
Upvotes: 0
Views: 130
Reputation: 473813
It might sound like too broad of an answer, but I would suggest to switch to a template engine, like mako
or jinja2
, instead of trying to manually construct HTML using the string concatenation. You would solve this kind of problem just by using the variable placeholders and built-in or custom filters.
As a bonus, you would get a nice separation of logic (your Python code) and presentation - the generated HTML. A much cleaner and more testable code.
Here is a working sample using jinja2
(created a custom rstrip
filter):
from jinja2 import Environment, FileSystemLoader
jiradb = [
{'total': 0, 'Resolution': None, 'key': u'CNSSDEBUG-151394', 'summary': u'[Lenovo][NFA344A][Win10] - [QCA6174_9377.WIN.1.0-10366-QCARMTFX86WZ-2] - Undetermined crash root cause'},
{'total': 1, 'Resolution': 'fixed', 'key': u'CNSSDEBUG-151395', 'summary': u'Some other summary'},
]
env = Environment(loader=FileSystemLoader('.'))
env.filters['rstrip'] = lambda value, s: value.rstrip(s) if value else ''
template = env.get_template('index.html')
print(template.render(jiradb=jiradb))
index.html
contents:
<table>
{% for item in jiradb %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ item.key|rstrip("\n!") }}</td>
<td>{{ item.summary|rstrip("\n!") }}</td>
<td>{{ item.Resolution|rstrip("\n!") }}</td>
</tr>
{% endfor %}
</table>
Prints:
<table>
<tr>
<td>1</td>
<td>CNSSDEBUG-151394</td>
<td>[Lenovo][NFA344A][Win10] - [QCA6174_9377.WIN.1.0-10366-QCARMTFX86WZ-2] - Undetermined crash root cause</td>
<td></td>
</tr>
<tr>
<td>2</td>
<td>CNSSDEBUG-151395</td>
<td>Some other summary</td>
<td>fixed</td>
</tr>
</table>
Upvotes: 4
Reputation: 8215
Extract each field from the dict using dict.get(key,default)
to avoid missing fields, and then use or
to cover the None
case
For example
item['Resolution'].rstrip('\n!')
becomes
(item.get('Resolution', None) or '').rstrip('\n!')
Then you probably want a helper function
def get_field(item, field, default=''):
return (item.get(field, None) or default).rstrip('\n!')
Then your loop is a little cleaner and you are safer from typos
........
for item in jiradb :
MailBody = MailBody + "<tr>"
MailBody = MailBody + "<td>" + str(icount) + "</td>"
print get_field(item, 'key')
MailBody = MailBody + "<td>" + get_field(item,'key') + "</td>"
MailBody = MailBody + "<td>" + get_field(item,'summary') + "</td>"
MailBody = MailBody + "<td>" + get_field(item,'Resolution') + "</td>"
icount = icount + 1
Upvotes: 2