Skip to main content

Hi,

I'm trying to execute a task in the Universal GUI. However I see a http 500 error when clicking on the task:

In the logs of Indicium (2021.2.18) there is a related error:

The given key 'import_start' was not present in the dictionary.

Where import_start is a task, also starting a process flow. Other tasks do work, tasks connected to a process flow don't. I don't understand why, as all the steps in the process flow should be compatible with the Universal GUI.

Any clues on how this can be fixed?

Full stack trace:

2021-09-09T14:26:29.0857181+02:00 8000019d-0004-fa00-b63f-84710c7967bb ERR] TSFMessagesMiddleware: An unhandled exception occurred while processing the request. (fffadd8a)
System.Collections.Generic.KeyNotFoundException: The given key 'import_start' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at System.Collections.ObjectModel.ReadOnlyDictionary`2.get_Item(TKey key)
   at Indicium.Controllers.StagingControllerBase.AllowTaskReport(ApiObj taskReportObj, KeySegment contextRootKey, List`1 propagationChain) in C:\azp\agent\_work\1\s\src\Indicium\Controllers\StagingControllerBase.cs:line 229
   at Indicium.Controllers.StagingController.stageTaskOrReport(ODataProperties props, ITSFObjOperation`1 stageAction, StagedResourceType type) in C:\azp\agent\_work\1\s\src\Indicium\Controllers\StagingController.cs:line 1151
   at Indicium.Controllers.StagingController.stageTaskOrReport(ODataProperties props, ITSFObjOperation`1 stageAction, StagedResourceType type) in C:\azp\agent\_work\1\s\src\Indicium\Controllers\StagingController.cs:line 1186
   at Indicium.Controllers.StagingController.StageTask() in C:\azp\agent\_work\1\s\src\Indicium\Controllers\StagingController.cs:line 1024
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Objectt] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.Invoke(HttpContext context)
   at Indicium.Middleware.Security.AuthenticationHeadersMiddleware.InvokeAsync(HttpContext context) in C:\azp\agent\_work\1\s\src\Indicium\Middleware\Authentication\AuthenticationHeadersMiddleware.cs:line 46
   at Indicium.Middleware.Security.SecurityHeadersMiddleware.InvokeAsync(HttpContext context, ContentSecurityPolicyBuilder cspBuilder) in C:\azp\agent\_work\1\s\src\Indicium\Middleware\Security\SecurityHeadersMiddleware.cs:line 49
   at Indicium.Middleware.Messages.TSFMessagesMiddleware.Invoke(HttpContext context, TSFRequestContext requestContext) in C:\azp\agent\_work\1\s\src\Indicium\Middleware\Messages\TSFMessageMiddleware.cs:line 83

 

Process flows having this issue:

 

I'm actually trying to execute the process flow behind this task via Indicium API, not necessarily the Universal GUI. I'm not sure if the process flow is triggered via the task. However according to the documentation the process flow api should be accessible:

https://docs.thinkwisesoftware.com/docs/indicium/process_flows.html

If i do a POST to /indicium/sf/appl/my_process_flow the return headers contain a location:

sf/appl/my_process_flow(48172af0-0d6a-45db-989f-2e8d81e974ff)/execute_tab_task_import

However when doing a POST to that location with the content of the task:

{

“file_name”: “file.zip”,

“file_content”: "”

}

It gives a http 400 “Invalid path.”.


Hello René,

The 500 error is due to an oversight in Indicium Universal. You can work around this issue by checking the ‘Context type output’ checkbox for the task ‘import_start’ within the subject ‘import’.
 

 

As for calling starting the process flow by means of an API call without the Universal GUI, this is possible with the following call:

POST
/sf/1282/empty_import/task_import_start  (NOTE, without the /stage segment)

The request body should contain a JSON object with the task parameters and its values.

With that said, your process flow will not run all the way to the Stop action with this one call, because it contains several process actions which Indicium cannot execute autonomously (Execute task, Refresh and Go to row). We recommend to only start process flows yourself with an API call if it is a system flow or if only the starting action is a non-system flow action. Otherwise you will need about 8 more API calls which can get quite complicated in order to complete this process flow.

As of the upcoming 2021.3 release of the Thinkwise platform, a new process action type called ‘Execute system task’ has been added. If you could replace the ‘Execute task’ process actions with ‘Execute system task’ process actions and skip the ‘Refresh’ and ‘Go to row’ process actions (perhaps based on the value of a task parameter), then your entire process flow will run from start to finish with the single API call described above.

What you could do to make this easier right now is create a separate process flow specifically for API calls. You can keep the ‘Execute task’ process action at the start and all of the ‘HTTP connector’ process actions. You can remove the ‘Refresh’ and ‘Go to row’ actions entirely. And finally you can implement the ‘import_start_project’ and ‘t_async’ tasks in the process procedures of the HTTP connectors.

I hope this helps.

Kind regards,

Vincent


Hello Vincent, thanks for the clear answer. I think we even should omit the process flow at all. For what we currently do it's only this:

  • POST /indicium/sf/appl/import -- create a new import record including the import xml file
  • POST /indicium/sf/appl/import_process -- process the just created import with a subroutine.

The only thing is that the import file can be another file type (zip). This is why there is a process flow attached, to convert the zip contents to a valid xml file. This is something that we do via an API via a http connector. But that could be a part of the new client application.

Dealing with process flows via the API can be complex due to the many steps and http calls that could be made. And you have to keep the API & client in sync with those steps. It's easier or better to keep the data model the same and do some more logic on the client side, creating less dependency on the API. I think the process flow API is only really usefull when it's a single call only, without interaction of a user. In this case it could be achieved by creating a separate process flow.

For the ‘oversight’, is this planned to be fixed in a near version?


Hello René,

Yes, we will fix this issue soon and you can expect to see it in the release notes when it is fixed. If you want more detailed status updates, I recommend creating a ticket in TCP. But it will be fixed either way.

Kind regards,

Vincent


Another question:

In the process flow we currently have an optional step that it can run asynchronously. This happens when the import is large (i.e. contains more than N xml nodes). This is done via an asynchronous task as part of the process flow.

Is this something that could reflect in the Indicium API? For example it returns by default a http 200, except when running asynchronous, then it should return a 202 Accepted with a location header in the result to verify the results.


Hello René,

This is currently not possible and it's not something that is scheduled to be implemented soon, but we have discussed features like that before. If you would like to see a feature like this, I recommend creating an Idea for it here.

Kind regards,

Vincent


Reply