diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py index 252b9264..ec3015dd 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py @@ -55,9 +55,18 @@ from spiffworkflow_backend.services.error_handling_service import ErrorHandlingS from spiffworkflow_backend.services.git_service import GitCommandError from spiffworkflow_backend.services.git_service import GitService from spiffworkflow_backend.services.message_service import MessageService +from spiffworkflow_backend.services.process_instance_lock_service import ( + ProcessInstanceLockService, +) from spiffworkflow_backend.services.process_instance_processor import ( ProcessInstanceProcessor, ) +from spiffworkflow_backend.services.process_instance_queue_service import ( + ProcessInstanceIsAlreadyLockedError, +) +from spiffworkflow_backend.services.process_instance_queue_service import ( + ProcessInstanceIsNotEnqueuedError, +) from spiffworkflow_backend.services.process_instance_queue_service import ( ProcessInstanceQueueService, ) @@ -129,7 +138,11 @@ def process_instance_run( try: processor.lock_process_instance("Web") processor.do_engine_steps(save=True) - except ApiError as e: + except ( + ApiError, + ProcessInstanceIsNotEnqueuedError, + ProcessInstanceIsAlreadyLockedError, + ) as e: ErrorHandlingService().handle_error(processor, e) raise e except Exception as e: @@ -143,7 +156,8 @@ def process_instance_run( task=task, ) from e finally: - processor.unlock_process_instance("Web") + if ProcessInstanceLockService.has_lock(process_instance.id): + processor.unlock_process_instance("Web") if not current_app.config["SPIFFWORKFLOW_BACKEND_RUN_BACKGROUND_SCHEDULER"]: MessageService.correlate_all_message_instances() diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_queue_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_queue_service.py index d9f900b2..d75d903f 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_queue_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_queue_service.py @@ -14,6 +14,10 @@ from spiffworkflow_backend.services.process_instance_lock_service import ( ) +class ProcessInstanceIsNotEnqueuedError(Exception): + pass + + class ProcessInstanceIsAlreadyLockedError(Exception): pass @@ -62,15 +66,20 @@ class ProcessInstanceQueueService: db.session.query(ProcessInstanceQueueModel) .filter( ProcessInstanceQueueModel.process_instance_id == process_instance.id, - ProcessInstanceQueueModel.locked_by == locked_by, ) .first() ) if queue_entry is None: + raise ProcessInstanceIsNotEnqueuedError( + f"{locked_by} cannot lock process instance {process_instance.id}. It" + " has not been enqueued." + ) + + if queue_entry.locked_by != locked_by: raise ProcessInstanceIsAlreadyLockedError( - f"Cannot lock process instance {process_instance.id}. " - "It has already been locked or has not been enqueued." + f"{locked_by} cannot lock process instance {process_instance.id}. " + f"It has already been locked by {queue_entry.locked_by}." ) ProcessInstanceLockService.lock(process_instance.id, queue_entry)