diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt index 54fbc7411..1687c9f4f 100644 --- a/.github/workflows/constraints.txt +++ b/.github/workflows/constraints.txt @@ -1,2 +1,2 @@ -pip==25.0 +pip==25.0.1 poetry==2.0.1 diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/message_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/message_service.py index 7378abea3..755fadf37 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/message_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/message_service.py @@ -5,6 +5,7 @@ from flask import g from SpiffWorkflow.bpmn import BpmnEvent # type: ignore from SpiffWorkflow.bpmn.specs.event_definitions.message import CorrelationProperty # type: ignore from SpiffWorkflow.bpmn.specs.mixins import StartEventMixin # type: ignore +from SpiffWorkflow.exceptions import SpiffWorkflowException # type: ignore from SpiffWorkflow.spiff.specs.event_definitions import MessageEventDefinition # type: ignore from spiffworkflow_backend.background_processing.celery_tasks.process_instance_task_producer import ( @@ -148,7 +149,7 @@ class MessageService: return None except Exception as exception: - db.session.rollback() + # db.session.rollback() # don't try to roll this back. The message failed, and we need to know why. message_instance_send.status = "failed" message_instance_send.failure_cause = str(exception) db.session.add(message_instance_send) @@ -160,6 +161,8 @@ class MessageService: processor_receive.save() else: db.session.commit() + if isinstance(exception, SpiffWorkflowException): + exception.add_note("The process instance encountered an error and failed after starting.") raise exception @classmethod diff --git a/spiffworkflow-backend/tests/data/message-start-with-error/message-start-with-error.bpmn b/spiffworkflow-backend/tests/data/message-start-with-error/message-start-with-error.bpmn new file mode 100644 index 000000000..a32ee0752 --- /dev/null +++ b/spiffworkflow-backend/tests/data/message-start-with-error/message-start-with-error.bpmn @@ -0,0 +1,45 @@ + + + + + Flow_0eqkmd7 + + + + + + + Flow_0ur3sgf + + + + Flow_0eqkmd7 + Flow_0ur3sgf + x = 1 '123'asdfasdf;lkj #$!@#$$$#@#@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_message_service.py b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_message_service.py index f9e72bf8f..f19073580 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_message_service.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_message_service.py @@ -1,7 +1,9 @@ import time from flask import Flask +from flask import g from flask.testing import FlaskClient +from spiffworkflow_backend.helpers.spiff_enum import ProcessInstanceExecutionMode from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.message_instance import MessageInstanceModel from spiffworkflow_backend.models.message_triggerable_process_model import MessageTriggerableProcessModel @@ -12,6 +14,7 @@ from spiffworkflow_backend.services.message_service import MessageService from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService from spiffworkflow_backend.services.spec_file_service import SpecFileService +from spiffworkflow_backend.services.workflow_execution_service import WorkflowExecutionServiceError from tests.spiffworkflow_backend.helpers.base_test import BaseTest from tests.spiffworkflow_backend.helpers.test_data import load_test_spec @@ -94,6 +97,42 @@ class TestMessageService(BaseTest): for message_instance in message_instances: assert message_instance.correlation_keys == {"invoice": {"po_number": 1001, "customer_id": "Sartography"}} + def test_start_process_with_message_when_failure( + self, + app: Flask, + client: FlaskClient, + with_db_and_bpmn_file_cleanup: None, + ) -> None: + """Assure we get a valid error when trying to start a process, and that process fails for some reason.""" + + # Load up the definition for the receiving process + # It has a message start event that should cause it to fire when a unique message comes through + # Fire up the first process + load_test_spec( + "test_group/message-start-with-error", + process_model_source_directory="message-start-with-error", + bpmn_file_name="message-start-with-error.bpmn", + ) + + # Now send in the message + user = self.find_or_create_user() + message_triggerable_process_model = MessageTriggerableProcessModel.query.filter_by( + message_name="test_bad_process" + ).first() + assert message_triggerable_process_model is not None + + MessageInstanceModel( + message_type="send", + name="test_bad_process", + payload={}, + user_id=user.id, + ) + g.user = user + try: + MessageService.run_process_model_from_message("test_bad_process", {}, ProcessInstanceExecutionMode.synchronous.value) + except WorkflowExecutionServiceError as e: + assert "The process instance encountered an error and failed after starting." in e.notes + def test_can_send_message_to_multiple_process_models( self, app: Flask,