95 lines
3.3 KiB
Python
95 lines
3.3 KiB
Python
# w.c.s. - web application for online forms
|
|
# Copyright (C) 2005-2017 Entr'ouvert
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import datetime
|
|
|
|
from qommon.misc import simplify
|
|
from qommon.xml_storage import XmlStorableObject
|
|
from wcs.formdef import FormDef
|
|
from wcs.workflows import Workflow
|
|
|
|
class LoggedError(XmlStorableObject):
|
|
_names = 'logged-errors'
|
|
_xml_tagname = 'error'
|
|
_indexes = ['tech_id']
|
|
_hashed_indexes = ['formdef_id', 'workflow_id']
|
|
|
|
summary = None
|
|
formdata_id = None
|
|
formdef_id = None
|
|
workflow_id = None
|
|
traceback = None
|
|
occurences_count = 0
|
|
first_occurence_timestamp = None
|
|
latest_occurence_timestamp = None
|
|
acked = False
|
|
|
|
# declarations for serialization
|
|
XML_NODES = [
|
|
('summary', 'str'), ('traceback', 'str'),
|
|
('formdata_id', 'str'), ('formdef_id', 'str'), ('workflow_id', 'str'),
|
|
('occurences_count', 'int'),
|
|
('first_occurence_timestamp', 'datetime'),
|
|
('latest_occurence_timestamp', 'datetime'),
|
|
('acked', 'bool')]
|
|
|
|
@classmethod
|
|
def record(cls, error_summary, plain_error_msg, publisher):
|
|
error = cls()
|
|
error.summary = error_summary
|
|
error.traceback = plain_error_msg
|
|
try:
|
|
context = publisher.substitutions.get_context_variables()
|
|
except:
|
|
return
|
|
|
|
formdef_urlname = context.get('form_slug')
|
|
if not formdef_urlname:
|
|
# cannot attach error to formdef, don't record in journal, it will
|
|
# still be sent by email to administrators.
|
|
return
|
|
|
|
error.formdata_id = context.get('form_number_raw')
|
|
if formdef_urlname:
|
|
formdef = FormDef.get_by_urlname(formdef_urlname)
|
|
error.formdef_id = formdef.id
|
|
error.workflow_id = formdef.workflow_id
|
|
|
|
error.first_occurence_timestamp = datetime.datetime.now()
|
|
error.id = '%s-%s' % (
|
|
error.first_occurence_timestamp.strftime('%Y%m%d-%H%M%S'),
|
|
error.tech_id,
|
|
)
|
|
existing_error = cls.get_on_index(error.tech_id, 'tech_id', ignore_errors=True)
|
|
if existing_error:
|
|
error = existing_error
|
|
error.occurences_count += 1
|
|
error.latest_occurence_timestamp = datetime.datetime.now()
|
|
error.store()
|
|
|
|
@property
|
|
def tech_id(self):
|
|
return '%s-%s-%s' % (self.formdef_id, self.workflow_id, simplify(self.summary))
|
|
|
|
def get_formdef(self):
|
|
return FormDef.get(self.formdef_id, ignore_errors=True)
|
|
|
|
def get_workflow(self):
|
|
return Workflow.get(self.workflow_id, ignore_errors=True)
|
|
|
|
def get_formdata(self):
|
|
return self.get_formdef().data_class().get(self.formdata_id, ignore_errors=True)
|