backoffice: use a template to render logged error (#47307)

This commit is contained in:
Frédéric Péters 2020-10-03 19:25:34 +02:00
parent ed81afac8b
commit 65cdabd1f0
4 changed files with 81 additions and 73 deletions

View File

@ -29,6 +29,7 @@ from wcs.logged_errors import LoggedError
class LoggedErrorDirectory(Directory):
_q_exports = ['', 'delete', 'ack']
do_not_call_in_templates = True
def __init__(self, parent_dir, error):
self.parent_dir = parent_dir
@ -38,84 +39,40 @@ class LoggedErrorDirectory(Directory):
get_response().breadcrumb.append(('%s/' % self.error.id, self.error.summary))
self.parent_dir.html_top(_('Logged Errors - %s') % self.error.summary)
get_response().filter['sidebar'] = self.get_sidebar()
return template.QommonTemplateResponse(
templates=['wcs/backoffice/logged-error.html'],
context={
'view': self,
'error': self.error,
'formdef': self.error.get_formdef(),
'workflow': self.error.get_workflow(),
'status': self.error.get_status(),
'status_item': self.error.get_status_item(),
'formdata': self.error.get_formdata(),
})
def error_expression_type_label(self):
return {
'python': _('Python Expression'),
'django': _('Django Expression'),
'template': _('Template'),
'text': _('Text'),
}.get(self.error.expression_type, _('Unknown'))
def get_html_traceback(self):
r = TemplateIO(html=True)
r += htmltext('<h2>%s</h2>') % self.error.summary
r += htmltext('<ul>')
r += htmltext(' <li>%s %s</li>') % (
_('First occurence:'),
localstrftime(self.error.first_occurence_timestamp))
r += htmltext(' <li>%s %s</li>') % (
_('Latest occurence:'),
localstrftime(self.error.latest_occurence_timestamp))
r += htmltext(' <li>%s %s</li>') % (_('Count:'), self.error.occurences_count)
formdef = self.error.get_formdef()
if formdef:
r += htmltext(' <li>%s <a href="%s">%s</a></li>') % (
_('%s:') % _(formdef.verbose_name),
formdef.get_admin_url(),
formdef.name)
workflow = self.error.get_workflow()
if workflow:
r += htmltext(' <li>%s <a href="/backoffice/workflows/%s/">%s</a></li>') % (
_('Workflow: '), workflow.id, workflow.name)
status = self.error.get_status()
if status:
r += htmltext('<ul>')
r += htmltext(
'<li>%s <a href="/backoffice/workflows/%s/status/%s/">%s</a></li>') % (
_('Status:'), workflow.id, status.id, status.name)
status_item = self.error.get_status_item()
if status_item:
r += htmltext(
'<li>%s <a href="/backoffice/workflows/%s/status/%s/items/%s/">%s</a></li>') % (
_('Action:'), workflow.id, status.id, status_item.id,
_(status_item.description))
r += htmltext('</ul>')
if self.error.expression or self.error.expression_type:
expression_title = {
'python': N_('Python Expression'),
'django': N_('Django Expression'),
'template': N_('Template'),
'text': N_('Text'),
}.get(self.error.expression_type, N_('Unknown'))
r += htmltext(' <li>%s <code>%s</code></li>') % (
_('%s:') % expression_title, self.error.expression)
if self.error.exception_class or self.error.exception_message:
r += htmltext(' <li>%s <code>%s: %s</code></li>') % (_('Error message:'),
self.error.exception_class,
self.error.exception_message)
if formdef:
formdata = self.error.get_formdata()
if formdata:
r += htmltext(' <li>%s <a href="%s">%s</a>') % (
_('Data: '), formdata.get_url(backoffice=True),
formdata.get_display_name())
r += htmltext(' (<a href="%sinspect">%s</a>)') % (
formdata.get_url(backoffice=True), _('inspector'))
r += htmltext('</li>')
r += htmltext('</ul>')
if not self.error.traceback:
return r.getvalue()
parts = (N_('Exception'), N_('Stack trace (most recent call first)'),
N_('Form'), N_('Cookies'), N_('Environment'))
current_part = None
for line in self.error.traceback.splitlines():
if line.endswith(':') and line.rstrip(':') in parts:
if current_part in parts[:2]:
r += htmltext('</pre>')
r += htmltext('</pre></div>')
elif current_part:
r += htmltext('</table>')
r += htmltext('</table></div>')
current_part = line.rstrip(':')
r += htmltext('<h3>%s</h3>') % _(current_part)
r += htmltext('<div class="section"><h3>%s</h3>') % _(current_part)
if current_part in parts[:2]:
r += htmltext('<pre class="traceback">')
else:
@ -128,9 +85,9 @@ class LoggedErrorDirectory(Directory):
re.split(r'\s+', line, maxsplit=1))
if current_part in parts[:2]:
r += htmltext('</pre>')
r += htmltext('</pre></div>')
elif current_part:
r += htmltext('</table>')
r += htmltext('</table></div>')
return r.getvalue()
def get_sidebar(self):

View File

@ -624,9 +624,12 @@ class FormData(StorableObject):
self.status = status
self.store()
def get_url(self, backoffice = False):
def get_url(self, backoffice=False):
return '%s%s/' % (self.formdef.get_url(backoffice=backoffice), self.id)
def get_backoffice_url(self):
return self.get_url(backoffice=True)
def get_api_url(self):
return '%s%s/' % (self.formdef.get_api_url(), self.id)

View File

@ -154,7 +154,10 @@ class LoggedError(XmlStorableObject):
def get_formdata(self):
if not self.formdata_id:
return None
return self.get_formdef().data_class().get(self.formdata_id, ignore_errors=True)
formdef = self.get_formdef()
if not formdef:
return None
return formdef.data_class().get(self.formdata_id, ignore_errors=True)
def get_status(self):
if not self.status_id:

View File

@ -0,0 +1,45 @@
{% extends "wcs/backoffice/base.html" %}
{% load i18n %}
{% block appbar-title %}{{ error.summary }}{% endblock %}
{% block content %}
<div class="section">
<ul>
<li>{% trans "First occurence:" %} {{ error.first_occurence_timestamp }}</li>
<li>{% trans "Latest occurence:" %} {{ error.latest_occurence_timestamp }}</li>
<li>{% trans "Count:" %} {{ error.occurences_count }}</li>
{% if formdef %}
<li>{% trans formdef.verbose_name %}{% trans ":" %} <a href="{{ formdef.get_admin_url }}">{{ formdef.name }}</a></li>
{% endif %}
{% if workflow %}
<li>{% trans "Workflow:" %} <a href="{{ workflow.get_admin_url }}">{{ workflow.name }}</a>
{% if status %}
<ul>
<li>{% trans "Status:" %} <a href="{{ workflow.get_admin_url }}status/{{ status.id }}/">{{ status.name }}</a></li>
{% if status_item %}
<li>{% trans "Action:" %} <a href="{{ workflow.get_admin_url }}status/{{ status.id }}/items/{{ status_item.id }}/">{% trans status_item.description %}</a></li>
{% endif %}
</ul>
{% endif %}
</li>
{% endif %}
{% if error.expression or error.expression_type %}
<li>{{ view.error_expression_type_label }}{% trans ":" %} <code>{{ error.expression }}</code></li>
{% endif %}
{% if error.exception_class or error.exception_message %}
<li>{% trans "Error message:" %} <code>{{ error.exception_class }}: {{ error.exception_message }}</code></li>
{% endif %}
{% if formdata %}
<li>{% trans "Data:" %} <a href="{{ formdata.get_backoffice_url }}">{{ formdata.get_display_name }}</a>
(<a href="{{ formdata.get_backoffice_url }}inspect">{% trans "inspector" %}</a>)</li>
{% endif %}
</ul>
</div>
{% if error.traceback %}
{{ view.get_html_traceback|safe }}
{% endif %}
{% endblock %}