catch and handle exceptions when attempting to complete human tasks (#380)

* catch and handle exceptions when attempting to complete human tasks w/ burnettk

* fix lint

---------

Co-authored-by: jasquat <jasquat@users.noreply.github.com>
Co-authored-by: burnettk <burnettk@users.noreply.github.com>
This commit is contained in:
jasquat 2023-07-12 10:16:05 -04:00 committed by GitHub
parent c2706c5bde
commit 4059f63fb6
4 changed files with 31 additions and 4 deletions

View File

@ -138,4 +138,17 @@ def error_detail_show(
status_code=400, status_code=400,
) )
) )
return make_response(jsonify(process_instance_event.error_details[0]), 200) if len(process_instance_event.error_details) < 1:
raise (
ApiError(
error_code="process_instance_event_error_details_not_found",
message=(
f"Error details for process instance event could not be found: {process_instance_event_id}. "
"Perhaps no exception was available."
),
status_code=400,
)
)
error_details = process_instance_event.error_details[0]
return make_response(jsonify(error_details), 200)

View File

@ -602,7 +602,7 @@ def task_save_draft(
error_code="process_instance_not_runnable", error_code="process_instance_not_runnable",
message=( message=(
f"Process Instance ({process_instance.id}) has status " f"Process Instance ({process_instance.id}) has status "
f"{process_instance.status} which does not allow tasks to be submitted." f"{process_instance.status} which does not allow draft data to be saved."
), ),
status_code=400, status_code=400,
) )

View File

@ -1541,7 +1541,14 @@ class ProcessInstanceProcessor:
) )
task_model.start_in_seconds = time.time() task_model.start_in_seconds = time.time()
self.bpmn_process_instance.run_task_from_id(spiff_task.id) task_exception = None
task_event = ProcessInstanceEventType.task_completed.value
try:
self.bpmn_process_instance.run_task_from_id(spiff_task.id)
except Exception as ex:
task_exception = ex
task_event = ProcessInstanceEventType.task_failed.value
task_model.end_in_seconds = time.time() task_model.end_in_seconds = time.time()
human_task.completed_by_user_id = user.id human_task.completed_by_user_id = user.id
@ -1559,9 +1566,10 @@ class ProcessInstanceProcessor:
ProcessInstanceTmpService.add_event_to_process_instance( ProcessInstanceTmpService.add_event_to_process_instance(
self.process_instance_model, self.process_instance_model,
ProcessInstanceEventType.task_completed.value, task_event,
task_guid=task_model.guid, task_guid=task_model.guid,
user_id=user.id, user_id=user.id,
exception=task_exception,
) )
# children of a multi-instance task has the attribute "triggered" set to True # children of a multi-instance task has the attribute "triggered" set to True
@ -1577,6 +1585,9 @@ class ProcessInstanceProcessor:
# this is the thing that actually commits the db transaction (on behalf of the other updates above as well) # this is the thing that actually commits the db transaction (on behalf of the other updates above as well)
self.save() self.save()
if task_exception is not None:
raise task_exception
def get_data(self) -> dict[str, Any]: def get_data(self) -> dict[str, Any]:
return self.bpmn_process_instance.data # type: ignore return self.bpmn_process_instance.data # type: ignore

View File

@ -25,6 +25,7 @@ from spiffworkflow_backend.models.process_model_cycle import ProcessModelCycleMo
from spiffworkflow_backend.models.task import Task from spiffworkflow_backend.models.task import Task
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.authorization_service import AuthorizationService from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.authorization_service import HumanTaskAlreadyCompletedError
from spiffworkflow_backend.services.authorization_service import HumanTaskNotFoundError from spiffworkflow_backend.services.authorization_service import HumanTaskNotFoundError
from spiffworkflow_backend.services.authorization_service import UserDoesNotHaveAccessToTaskError from spiffworkflow_backend.services.authorization_service import UserDoesNotHaveAccessToTaskError
from spiffworkflow_backend.services.git_service import GitCommandError from spiffworkflow_backend.services.git_service import GitCommandError
@ -524,6 +525,8 @@ class ProcessInstanceService:
processor.process_instance_model.id, str(spiff_task.id), g.user processor.process_instance_model.id, str(spiff_task.id), g.user
) )
can_complete = True can_complete = True
except HumanTaskAlreadyCompletedError:
can_complete = False
except HumanTaskNotFoundError: except HumanTaskNotFoundError:
can_complete = False can_complete = False
except UserDoesNotHaveAccessToTaskError: except UserDoesNotHaveAccessToTaskError: