Azure / azure-functions-eventhubs-extension

Event Hubs extension for Azure Functions
MIT License
20 stars 26 forks source link

EventHubs Trigger with "cardinality": "many" fails when input is not valid JSON #118

Closed mhoeger closed 1 month ago

mhoeger commented 6 years ago

When "cardinality": "many" is set on an Event Hubs trigger (as it should be for best perf), the error below is thrown unless the original input is valid json. This conflicts with v1 behavior and breaks the template example

System.Private.CoreLib: Exception while executing function: Functions.eventhub. Microsoft.Azure.WebJobs.Host: Exception binding parameter 'myEventHubMessages'. Microsoft.Azure.WebJobs.Host: Binding parameters to complex objects (such as 'Object') uses Json.NET serialization.
1. Bind the parameter type as 'string' instead of 'Object' to get the raw values and avoid JSON deserialization, or
2. Change the queue payload to be valid json. The JSON parser failed: Unexpected character encountered while parsing value: E. Path '', line 0, position 0.

Workaround: If you know your input may not be valid json, add "dataType": "string" to trigger binding. Example function.json:

{
  "bindings": [
    {
      "type": "eventHubTrigger",
      "name": "myEventHubMessages",
      "direction": "in",
      "eventHubName": "samples-workitems",
      "connection": "EventHubReceiver",
      "cardinality": "many",
      "dataType": "string"
    }
  ]
}
Complete stack trace

=> System.Collections.Generic.Dictionary`2[System.String,System.Object]
Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.eventhub ---> System.InvalidOperationException: Exception binding parameter 'myEventHubMessages' ---> System.InvalidOperationException: Binding parameters to complex objects (such as 'Object') uses Json.NET serialization.
1. Bind the parameter type as 'string' instead of 'Object' to get the raw values and avoid JSON deserialization, or
2. Change the queue payload to be valid json. The JSON parser failed: Unexpected character encountered while parsing value: T. Path '', line 0, position 0.

   at Microsoft.Azure.WebJobs.Host.Triggers.PocoTriggerArgumentBinding`2.ConvertAsync(TMessage value, Dictionary`2 bindingData, ValueBindingContext context) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Triggers\TriggerArgumentBinding\PocoTriggerArgumentBinding.cs:line 57
   at Microsoft.Azure.WebJobs.Host.ArrayTriggerArgumentBinding`2.BindAsync(TTriggerValue value, ValueBindingContext context) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Triggers\TriggerArgumentBinding\ArraryTriggerArgumentBinding.cs:line 37
   at Microsoft.Azure.WebJobs.Host.Triggers.TriggeredFunctionBinding`1.BindCoreAsync(ValueBindingContext context, Object value, IDictionary`2 parameters) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Triggers\TriggeredFunctionBinding.cs:line 57
   --- End of inner exception stack trace ---
   at Microsoft.Azure.WebJobs.Host.Executors.DelayedException.Throw() in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DelayedException.cs:line 27
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstance instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 460
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstance instance, ParameterHelper parameterHelper, IFunctionOutputDefinition outputDefinition, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 426
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstance instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 231
   --- End of inner exception stack trace ---
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstance instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 275
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsync(IFunctionInstance functionInstance, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 75
fail: Function.eventhub[0]

Additional context: PR with first pass at fix: https://github.com/Azure/azure-functions-host/pull/3170 Issue was brought to attention here: https://github.com/Azure/azure-functions-host/issues/2815

mhoeger commented 6 years ago

The fix involves creating a DefaultType for the EventHubs trigger attribute and making sure that it is registered in the metadata provider

cc: @pragnagopa

rohsyl commented 1 month ago

Hi, I've having the same issue while using Typescript v4. And i dont find a way to specify the dataType. I need to work with binary data.

Code :

export async function LiveData(messages: any | any[], context: InvocationContext): Promise<void> {
    // ...
}

app.eventHub('LiveData', {
    connection: 'Connection',
    eventHubName: 'messages/events',
    cardinality: 'many',
    consumerGroup: '%EventHubConsumerGroup%',
    handler: LiveData,
});

Error:

[Error] Executed 'Functions.LiveData' (Failed, Id=, Duration=84ms)
Binding parameters to complex objects (such as 'Object') uses Json.NET serialization.
1. Bind the parameter type as 'string' instead of 'Object' to get the raw values and avoid JSON deserialization, or
2. Change the queue payload to be valid json. The JSON parser failed: Unexpected character encountered while parsing value: ⸮. Path '', line 0, position 0.