diff --git a/SpiffWorkflow/SpiffWorkflow/bpmn/parser/BpmnParser.py b/SpiffWorkflow/SpiffWorkflow/bpmn/parser/BpmnParser.py index 6b98bb8a..7741c801 100644 --- a/SpiffWorkflow/SpiffWorkflow/bpmn/parser/BpmnParser.py +++ b/SpiffWorkflow/SpiffWorkflow/bpmn/parser/BpmnParser.py @@ -48,7 +48,7 @@ from .task_parsers import ( GatewayParser, ConditionalGatewayParser, CallActivityParser, - ScriptTaskParser, + ScriptTaskParser, SubWorkflowParser, ) from .event_parsers import ( @@ -254,9 +254,9 @@ class BpmnParser(object): def create_parser(self, node, filename=None, lane=None): parser = self.PROCESS_PARSER_CLASS(self, node, self.namespaces, filename=filename, lane=lane) if parser.get_id() in self.process_parsers: - raise ValidationException('Duplicate process ID', node=node, file_name=filename) + raise ValidationException(f'Duplicate process ID: {parser.get_id()}', node=node, file_name=filename) if parser.get_name() in self.process_parsers_by_name: - raise ValidationException('Duplicate process name', node=node, file_name=filename) + raise ValidationException(f'Duplicate process name: {parser.get_name()}', node=node, file_name=filename) self.process_parsers[parser.get_id()] = parser self.process_parsers_by_name[parser.get_name()] = parser diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/exceptions/api_error.py b/spiffworkflow-backend/src/spiffworkflow_backend/exceptions/api_error.py index 9fe08bec..bb6d84f4 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/exceptions/api_error.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/exceptions/api_error.py @@ -242,6 +242,10 @@ def handle_exception(exception: Exception) -> flask.wrappers.Response: api_exception = None if isinstance(exception, ApiError): api_exception = exception + elif isinstance(exception, SpiffWorkflowException): + api_exception = ApiError.from_workflow_exception( + "unexpected_workflow_exception", "Unexpected Workflow Error", exception + ) else: api_exception = ApiError( error_code=error_code, diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py index 2879c120..6f272287 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/tasks_controller.py @@ -275,7 +275,7 @@ def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response ) from exception if task.data: - _update_form_schema_with_task_data_as_needed(form_dict, task) + _update_form_schema_with_task_data_as_needed(form_dict, task, spiff_task) if form_contents: task.form_schema = form_dict @@ -588,7 +588,9 @@ def _get_spiff_task_from_process_instance( # originally from: https://bitcoden.com/answers/python-nested-dictionary-update-value-where-any-nested-key-matches -def _update_form_schema_with_task_data_as_needed(in_dict: dict, task: Task) -> None: +def _update_form_schema_with_task_data_as_needed( + in_dict: dict, task: Task, spiff_task: SpiffTask +) -> None: """Update_nested.""" if task.data is None: return None @@ -615,7 +617,7 @@ def _update_form_schema_with_task_data_as_needed(in_dict: dict, task: Task) -> N f" '{task_data_var}' but it doesn't exist in" " the Task Data." ), - task=task, + task=spiff_task, ) raise ( ApiError.from_workflow_exception( @@ -648,11 +650,11 @@ def _update_form_schema_with_task_data_as_needed(in_dict: dict, task: Task) -> N in_dict[k] = options_for_react_json_schema_form elif isinstance(value, dict): - _update_form_schema_with_task_data_as_needed(value, task) + _update_form_schema_with_task_data_as_needed(value, task, spiff_task) elif isinstance(value, list): for o in value: if isinstance(o, dict): - _update_form_schema_with_task_data_as_needed(o, task) + _update_form_schema_with_task_data_as_needed(o, task, spiff_task) def _get_potential_owner_usernames(assigned_user: AliasedClass) -> Any: diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py index d0c43fb2..d00ed011 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py @@ -499,7 +499,10 @@ class ProcessModelService(FileSystemService): if name is None: raise ApiError( error_code="missing_name_of_process_model", - message="Missing name of process model. It should be given", + message=( + "Missing name of process model. Path not found:" + f" {json_file_path}" + ), ) process_model_info = ProcessModelInfo( diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index d68bd3da..a20e7b7b 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -41,7 +41,10 @@ export default function TaskShow() { // instead of passing the process model identifier in through the params HttpService.makeCallToBackend({ path: url, - successCallback: setUserTasks, + successCallback: (tasks: any) => { + setDisabled(false); + setUserTasks(tasks); + }, onUnauthorized: () => {}, failureCallback: (error: any) => { addError(error); @@ -59,7 +62,6 @@ export default function TaskShow() { const processSubmitResult = (result: any) => { removeError(); - setDisabled(false); if (result.ok) { navigate(`/tasks`); } else if (result.process_instance_id) { @@ -212,10 +214,16 @@ export default function TaskShow() { reactFragmentToHideSubmitButton =
; } - if (task.type === 'Manual Task' && task.state === 'READY') { + if (task.state === 'READY') { + let buttonText = 'Submit'; + if (task.type === 'Manual Task') { + buttonText = 'Continue'; + } reactFragmentToHideSubmitButton = (
- +
); } @@ -228,6 +236,7 @@ export default function TaskShow() {