Fix that dreadful unknown "KeyError" exception that was cropping up.
Adding a bit of detail to the spiffworkflow exceptions when a duplicate process model is found. Disable the submit button on tasks after you click submit (avoid the double click and give users a better experience)
This commit is contained in:
parent
cd7c109a00
commit
d010c2bce6
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 = <div />;
|
||||
}
|
||||
|
||||
if (task.type === 'Manual Task' && task.state === 'READY') {
|
||||
if (task.state === 'READY') {
|
||||
let buttonText = 'Submit';
|
||||
if (task.type === 'Manual Task') {
|
||||
buttonText = 'Continue';
|
||||
}
|
||||
reactFragmentToHideSubmitButton = (
|
||||
<div>
|
||||
<Button type="submit">Continue</Button>
|
||||
<Button type="submit" disabled={disabled}>
|
||||
{buttonText}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -228,6 +236,7 @@ export default function TaskShow() {
|
|||
<Grid fullWidth condensed>
|
||||
<Column sm={4} md={5} lg={8}>
|
||||
<Form
|
||||
disabled={disabled}
|
||||
formData={taskData}
|
||||
onSubmit={handleFormSubmit}
|
||||
schema={jsonSchema}
|
||||
|
|
Loading…
Reference in New Issue