Assure we log reasonably clear errors when executing scheduled tasks in the background, so that sentry can pick them up and they can be addressed effectively.
This commit is contained in:
parent
bef35e4bec
commit
1916c4ff54
|
@ -98,15 +98,18 @@ class WorkflowService(object):
|
|||
def do_waiting():
|
||||
records = db.session.query(WorkflowModel).filter(WorkflowModel.status==WorkflowStatus.waiting).all()
|
||||
for workflow_model in records:
|
||||
# fixme: Try catch with a very explicit error about the study, workflow and task that failed.
|
||||
try:
|
||||
app.logger.info('Processing workflow %s' % workflow_model.id)
|
||||
processor = WorkflowProcessor(workflow_model)
|
||||
processor.bpmn_workflow.refresh_waiting_tasks()
|
||||
processor.bpmn_workflow.do_engine_steps()
|
||||
processor.save()
|
||||
except:
|
||||
app.logger.error('Failed to process workflow')
|
||||
except Exception as e:
|
||||
app.logger.error(f"Error running waiting task for workflow #%i (%s) for study #%i. %s" %
|
||||
(workflow_model.id,
|
||||
workflow_model.workflow_spec.name,
|
||||
workflow_model.study_id,
|
||||
str(e)))
|
||||
|
||||
@staticmethod
|
||||
@timeit
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_0ilr8m3" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.3">
|
||||
<bpmn:process id="timer" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1pahvlr</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:manualTask id="get_coffee" name="Eat Spam">
|
||||
<bpmn:incoming>Flow_1pahvlr</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1pvkgnu</bpmn:outgoing>
|
||||
</bpmn:manualTask>
|
||||
<bpmn:manualTask id="back_to_work" name="Get Back To Work">
|
||||
<bpmn:incoming>Flow_1pvkgnu</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1ekgt3x</bpmn:outgoing>
|
||||
</bpmn:manualTask>
|
||||
<bpmn:endEvent id="Event_03w65sk">
|
||||
<bpmn:incoming>Flow_1ekgt3x</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1ekgt3x" sourceRef="back_to_work" targetRef="Event_03w65sk" />
|
||||
<bpmn:sequenceFlow id="Flow_1pvkgnu" sourceRef="get_coffee" targetRef="back_to_work" />
|
||||
<bpmn:sequenceFlow id="Flow_1pahvlr" sourceRef="StartEvent_1" targetRef="get_coffee" />
|
||||
<bpmn:sequenceFlow id="Flow_05lcpdf" sourceRef="Event_1txv76c" targetRef="Activity_0onlql2" />
|
||||
<bpmn:scriptTask id="Activity_0onlql2" name="Do Bad Burp">
|
||||
<bpmn:incoming>Flow_05lcpdf</bpmn:incoming>
|
||||
<bpmn:script># Tries to burp, failes.
|
||||
my_burp = non_existent_burp_variable</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
<bpmn:boundaryEvent id="Event_1txv76c" name="burp?" attachedToRef="get_coffee">
|
||||
<bpmn:outgoing>Flow_05lcpdf</bpmn:outgoing>
|
||||
<bpmn:timerEventDefinition id="TimerEventDefinition_1rvot87">
|
||||
<bpmn:timeDuration xsi:type="bpmn:tFormalExpression">timedelta(seconds=.25)</bpmn:timeDuration>
|
||||
</bpmn:timerEventDefinition>
|
||||
</bpmn:boundaryEvent>
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="timer">
|
||||
<bpmndi:BPMNEdge id="Flow_1pahvlr_di" bpmnElement="Flow_1pahvlr">
|
||||
<di:waypoint x="215" y="117" />
|
||||
<di:waypoint x="260" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1pvkgnu_di" bpmnElement="Flow_1pvkgnu">
|
||||
<di:waypoint x="360" y="117" />
|
||||
<di:waypoint x="533" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1ekgt3x_di" bpmnElement="Flow_1ekgt3x">
|
||||
<di:waypoint x="633" y="117" />
|
||||
<di:waypoint x="682" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_05lcpdf_di" bpmnElement="Flow_05lcpdf">
|
||||
<di:waypoint x="300" y="175" />
|
||||
<di:waypoint x="300" y="180" />
|
||||
<di:waypoint x="380" y="180" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0tjl9dd_di" bpmnElement="get_coffee">
|
||||
<dc:Bounds x="260" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_15zi5m4_di" bpmnElement="back_to_work">
|
||||
<dc:Bounds x="533" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_03w65sk_di" bpmnElement="Event_03w65sk">
|
||||
<dc:Bounds x="682" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_05taua6_di" bpmnElement="Activity_0onlql2">
|
||||
<dc:Bounds x="380" y="140" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_0xco4d9_di" bpmnElement="Event_1txv76c">
|
||||
<dc:Bounds x="282" y="139" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="286" y="182" width="29" height="14" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -1,13 +1,13 @@
|
|||
import json
|
||||
import time
|
||||
|
||||
from crc.services.workflow_processor import WorkflowProcessor
|
||||
from tests.base_test import BaseTest
|
||||
from crc.models.workflow import WorkflowStatus, WorkflowModel
|
||||
from crc import db
|
||||
from crc.api.common import ApiError
|
||||
from crc.models.task_event import TaskEventModel, TaskEventSchema
|
||||
from crc.services.workflow_service import WorkflowService
|
||||
from crc.services.workflow_processor import WorkflowProcessor
|
||||
|
||||
|
||||
class TestTimerEvent(BaseTest):
|
||||
|
@ -28,3 +28,19 @@ class TestTimerEvent(BaseTest):
|
|||
wf = db.session.query(WorkflowModel).filter(WorkflowModel.id == workflow.id).first()
|
||||
self.assertTrue(wf.status != WorkflowStatus.waiting)
|
||||
|
||||
def test_waiting_event_error(self):
|
||||
workflow = self.create_workflow('timer_event_error')
|
||||
processor = WorkflowProcessor(workflow)
|
||||
processor.do_engine_steps()
|
||||
processor.save()
|
||||
time.sleep(.3) # our timer is at .25 sec so we have to wait for it
|
||||
# get done waiting
|
||||
wf = db.session.query(WorkflowModel).filter(WorkflowModel.id == workflow.id).first()
|
||||
self.assertTrue(wf.status == WorkflowStatus.waiting)
|
||||
with self.assertLogs('crc', level='ERROR') as cm:
|
||||
WorkflowService.do_waiting()
|
||||
self.assertEqual(1, len(cm.output))
|
||||
self.assertRegexpMatches(cm.output[0], "workflow #1")
|
||||
self.assertRegexpMatches(cm.output[0], "study #1")
|
||||
|
||||
self.assertTrue(wf.status == WorkflowStatus.waiting)
|
||||
|
|
Loading…
Reference in New Issue