elsa-core icon indicating copy to clipboard operation
elsa-core copied to clipboard

[BUG] Different type received in the input when using mass transit

Open MariusVuscanNx opened this issue 10 months ago • 1 comments

Description

We created a INotificationHandler<WorkflowExecuted> and we tried getting the value of an input. That value was of type dictionary when using mass-transit and of type expando object when not using mass-transit.

Steps to Reproduce

  • Define a new
  • Try to access the input
public async Task HandleAsync(WorkflowExecuted notification, CancellationToken cancellationToken)
{    
  var workflowInput = notification.WorkflowExecutionContext.Input;
  workflowInput.TryGetValue("Headers", out var headersInput)

  1. Attachments: No attachments

  2. Reproduction Rate: Indicate how often the bug occurs when following these steps (e.g., "every time", "intermittently: about 50% of the time"). Every time.

  3. Video/Screenshots: Sometimes, complex behaviors are better shown than described. If you think a video or screenshots would help clarify the issue, please include them. No screenshots or video.

  4. Additional Configuration: Mass transit enabled/disabled.

Expected Behavior

Received the same type no matter which provider you use.

Actual Behavior

Different type received when inspecting the headersInput depending if mass-transit in enabled or not.

Screenshots

No screenshot.

Environment

Elsa version 3.1.0-preview.1209

Log Output

No log.

Troubleshooting Attempts

No attempt.

Additional Context

No additional data.

Related Issues

No related issue.

MariusVuscanNx avatar Apr 18 '24 09:04 MariusVuscanNx

Based on the context provided, it seems you are encountering an issue where the type of the workflowInput variable differs depending on whether MassTransit is enabled or not. This inconsistency is causing trouble when you try to access the input in your INotificationHandler<WorkflowExecuted> implementation.

In Elsa, inputs to workflows are expected to be dictionaries with string keys and object values, as seen in the examples provided in the context. However, when using different messaging or serialization mechanisms, the actual type of the object that gets deserialized might differ. For instance, with MassTransit, it might be deserialized into a dictionary, while without MassTransit, it might be deserialized into an ExpandoObject.

To handle this, you could write some conditional logic that checks the type of headersInput and processes it accordingly. Here's a simplified example of how you might handle both cases:

public async Task HandleAsync(WorkflowExecuted notification, CancellationToken cancellationToken)
{
    var workflowInput = notification.WorkflowExecutionContext.Input;
    if (workflowInput.TryGetValue("Headers", out var headersInput))
    {
        if (headersInput is IDictionary<string, object> headersDictionary)
        {
            // Process headers as dictionary
        }
        else if (headersInput is ExpandoObject headersExpando)
        {
            // Convert ExpandoObject to dictionary if necessary and process
            var headersDictionary = new Dictionary<string, object>(headersExpando);
            // Process headers as dictionary
        }
        else
        {
            // Handle unexpected type
        }
    }
}

This approach ensures that regardless of the underlying type, you can work with the input as a dictionary.

For a more robust solution, you might want to look into custom serialization settings or hooks provided by MassTransit and Elsa to ensure consistent deserialization of workflow inputs.

Since this seems to be a behavior by design or a limitation of the current implementation, you might also want to consider filing an issue on the Elsa GitHub repository to discuss this with the maintainers and possibly improve the documentation or functionality around this area.

This comment was generated by Glime.

glime-ai[bot] avatar Apr 18 '24 09:04 glime-ai[bot]