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,
)
)
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",
message=(
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,
)

View File

@ -1541,7 +1541,14 @@ class ProcessInstanceProcessor:
)
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()
human_task.completed_by_user_id = user.id
@ -1559,9 +1566,10 @@ class ProcessInstanceProcessor:
ProcessInstanceTmpService.add_event_to_process_instance(
self.process_instance_model,
ProcessInstanceEventType.task_completed.value,
task_event,
task_guid=task_model.guid,
user_id=user.id,
exception=task_exception,
)
# 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)
self.save()
if task_exception is not None:
raise task_exception
def get_data(self) -> dict[str, Any]:
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.user import UserModel
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 UserDoesNotHaveAccessToTaskError
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
)
can_complete = True
except HumanTaskAlreadyCompletedError:
can_complete = False
except HumanTaskNotFoundError:
can_complete = False
except UserDoesNotHaveAccessToTaskError: