26 |
26 |
editable.status = 'deleted_status_id'
|
27 |
27 |
workflow.store()
|
28 |
28 |
# go back to st1
|
29 |
|
@@ -1710,6 +1712,13 @@ def test_form_multi_page_post_edit(pub):
|
|
29 |
@@ -1710,6 +1712,27 @@ def test_form_multi_page_post_edit(pub):
|
30 |
30 |
resp = resp.forms[0].submit('submit')
|
31 |
31 |
resp = resp.follow()
|
32 |
32 |
assert formdef.data_class().get(data_id).status == 'wf-%s' % st1.id # stay on st1
|
... | ... | |
37 |
37 |
+ assert logged_error.workflow_id == workflow.id
|
38 |
38 |
+ assert logged_error.status_id == st1.id
|
39 |
39 |
+ assert logged_error.status_item_id == editable.id
|
|
40 |
+ assert logged_error.occurences_count == 1
|
|
41 |
+
|
|
42 |
+ # do it again: increment logged_error.occurences_count
|
|
43 |
+ page = login(get_app(pub), username='foo', password='foo').get('/test/%s/' % data_id)
|
|
44 |
+ resp = page.forms[0].submit('button_editable')
|
|
45 |
+ resp = resp.follow()
|
|
46 |
+ resp.forms[0]['f1'] = 'foo3'
|
|
47 |
+ resp = resp.forms[0].submit('submit')
|
|
48 |
+ resp = resp.forms[0].submit('submit')
|
|
49 |
+ resp = resp.follow()
|
|
50 |
+ assert formdef.data_class().get(data_id).status == 'wf-%s' % st1.id # stay on st1
|
|
51 |
+ assert LoggedError.count() == 1
|
|
52 |
+ logged_error = LoggedError.select()[0]
|
|
53 |
+ assert logged_error.occurences_count == 2
|
40 |
54 |
|
41 |
55 |
def test_form_count_dispatching(pub):
|
42 |
56 |
user = create_user(pub)
|
|
57 |
@@ -4359,7 +4382,7 @@ def test_logged_errors(pub):
|
|
58 |
assert LoggedError.count() == 1
|
|
59 |
|
|
60 |
error = LoggedError.get_on_index(
|
|
61 |
- '34-12-zerodivisionerror-integer-division-or-modulo-by-zero', 'tech_id')
|
|
62 |
+ '34-12-None-None-zerodivisionerror-integer-division-or-modulo-by-zero', 'tech_id')
|
|
63 |
assert error.occurences_count == 2
|
|
64 |
|
|
65 |
assert len(LoggedError.get_ids_with_indexed_value('formdef_id', '34')) == 1
|
43 |
66 |
diff --git a/wcs/admin/logged_errors.py b/wcs/admin/logged_errors.py
|
44 |
|
index c2373925..019f009f 100644
|
|
67 |
index c2373925..4ddf1cdb 100644
|
45 |
68 |
--- a/wcs/admin/logged_errors.py
|
46 |
69 |
+++ b/wcs/admin/logged_errors.py
|
47 |
70 |
@@ -56,6 +56,19 @@ class LoggedErrorDirectory(Directory):
|
... | ... | |
75 |
98 |
parts = (N_('Exception'), N_('Stack trace (most recent call first)'),
|
76 |
99 |
N_('Form'), N_('Cookies'), N_('Environment'))
|
77 |
100 |
current_part = None
|
|
101 |
@@ -105,10 +122,6 @@ class LoggedErrorDirectory(Directory):
|
|
102 |
r += htmltext('<li>%s</li>' % _('Acked'))
|
|
103 |
r += htmltext('<li><a href="delete">%s</a></li>') % _('Delete')
|
|
104 |
r += htmltext('</ul>')
|
|
105 |
- if get_publisher().logger.error_email:
|
|
106 |
- r += htmltext('<div class="infonotice"><p>')
|
|
107 |
- r += _('This error has also been sent by email to %s.') % get_publisher().logger.error_email
|
|
108 |
- r += htmltext('</p></div>')
|
|
109 |
return r.getvalue()
|
|
110 |
|
|
111 |
def ack(self):
|
78 |
112 |
diff --git a/wcs/logged_errors.py b/wcs/logged_errors.py
|
79 |
|
index 39e568fb..50f932b2 100644
|
|
113 |
index 39e568fb..4030d2b6 100644
|
80 |
114 |
--- a/wcs/logged_errors.py
|
81 |
115 |
+++ b/wcs/logged_errors.py
|
82 |
116 |
@@ -31,6 +31,8 @@ class LoggedError(XmlStorableObject):
|
... | ... | |
88 |
122 |
traceback = None
|
89 |
123 |
occurences_count = 0
|
90 |
124 |
first_occurence_timestamp = None
|
91 |
|
@@ -41,32 +43,43 @@ class LoggedError(XmlStorableObject):
|
|
125 |
@@ -41,32 +43,41 @@ class LoggedError(XmlStorableObject):
|
92 |
126 |
XML_NODES = [
|
93 |
127 |
('summary', 'str'), ('traceback', 'str'),
|
94 |
128 |
('formdata_id', 'str'), ('formdef_id', 'str'), ('workflow_id', 'str'),
|
... | ... | |
100 |
134 |
|
101 |
135 |
@classmethod
|
102 |
136 |
- def record(cls, error_summary, plain_error_msg, publisher):
|
103 |
|
+ def record(cls, error_summary, plain_error_msg=None, formdata=None, formdata_id=None,
|
|
137 |
+ def record(cls, error_summary, plain_error_msg=None, formdata=None,
|
104 |
138 |
+ formdef=None, workflow=None, status=None, status_item=None):
|
105 |
139 |
error = cls()
|
106 |
140 |
error.summary = error_summary
|
... | ... | |
116 |
150 |
+ error.formdata_id = str(formdata.id)
|
117 |
151 |
+ error.formdef_id = formdata.formdef.id
|
118 |
152 |
+ error.workflow_id = formdata.formdef.workflow.id
|
119 |
|
+ else:
|
120 |
|
+ error.formdata_id = str(formdata_id)
|
121 |
|
+ if formdef:
|
122 |
|
+ error.formdef_id = formdef.id
|
123 |
|
+ error.workflow_id = formdef.workflow.id
|
|
153 |
+ elif formdef:
|
|
154 |
+ error.formdef_id = formdef.id
|
|
155 |
+ error.workflow_id = formdef.workflow.id
|
124 |
156 |
+
|
125 |
157 |
+ if not error.formdef_id:
|
126 |
158 |
# cannot attach error to formdef, don't record in journal, it will
|
... | ... | |
144 |
176 |
|
145 |
177 |
error.first_occurence_timestamp = datetime.datetime.now()
|
146 |
178 |
error.id = '%s-%s' % (
|
147 |
|
@@ -80,9 +93,26 @@ class LoggedError(XmlStorableObject):
|
|
179 |
@@ -80,9 +91,27 @@ class LoggedError(XmlStorableObject):
|
148 |
180 |
error.latest_occurence_timestamp = datetime.datetime.now()
|
149 |
181 |
error.store()
|
150 |
182 |
|
... | ... | |
161 |
193 |
+ # still be sent by email to administrators.
|
162 |
194 |
+ return
|
163 |
195 |
+ formdef = FormDef.get_by_urlname(formdef_urlname)
|
164 |
|
+ cls.record(error_summary, plain_error_msg, formdata_id=formdata_id,
|
|
196 |
+ formdata = formdef.data_class().get(formdata_id, ignore_errors=True)
|
|
197 |
+ cls.record(error_summary, plain_error_msg, formdata=formdata,
|
165 |
198 |
+ formdef=formdef, workflow=formdef.workflow)
|
166 |
199 |
+
|
167 |
200 |
@property
|
... | ... | |
172 |
205 |
|
173 |
206 |
def get_formdef(self):
|
174 |
207 |
return FormDef.get(self.formdef_id, ignore_errors=True)
|
175 |
|
@@ -91,4 +121,26 @@ class LoggedError(XmlStorableObject):
|
|
208 |
@@ -91,4 +120,26 @@ class LoggedError(XmlStorableObject):
|
176 |
209 |
return Workflow.get(self.workflow_id, ignore_errors=True)
|
177 |
210 |
|
178 |
211 |
def get_formdata(self):
|