elsa-workflows / elsa-core

A .NET workflows library
https://v3.elsaworkflows.io/
MIT License
5.87k stars 1.06k forks source link

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

Open MariusVuscanNx opened 3 weeks ago

MariusVuscanNx commented 3 weeks ago

Description

We created a INotificationHandler 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



3. **Attachments**:
No attachments

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

5. **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.

6. **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.
glime-ai[bot] commented 3 weeks ago

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.