Azure / azure-functions-dotnet-worker

Azure Functions out-of-process .NET language worker
MIT License
419 stars 181 forks source link

Silent failures on batch out - Queue output #219

Open pragnagopa opened 3 years ago

pragnagopa commented 3 years ago

Related issue: https://github.com/Azure/azure-functions-dotnet-worker/issues/124

Very likely issue with the user code below:

using System;
using System.Collections.Generic;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace dotnet5Test
{
    public static class testqueue
    {
        [Function("testqueue")]
        public static IEnumerable<MyOutputType> Run([QueueTrigger("testqueue", Connection = "")] string myQueueItem,
            FunctionContext context)
        {
            var logger = context.GetLogger("testqueue");
            logger.LogInformation($"C# Queue trigger function processed: {myQueueItem}");

            return new List<MyOutputType>() {
                new MyOutputType()
                {
                    Name = "Sun"
                },
                new MyOutputType()
                {
                      Name = "Mon"
                }
            };
        }
    }

    public class MyOutputType
    {
        [QueueOutput("myQueue")]
        public string Name { get; set; }
    }
}

Function execution succeeds without errors and not writing to output queue

fabiocav commented 3 years ago

@mhoeger for awareness. Your changes should address this as well.

ankitkumarr commented 3 years ago

@pragnagopa, I think the way to define output binding in this case would be in the method. That combined with Marie's cardinality changes should light this up. --

public static class testqueue
{
    [Function("testqueue")]
    [QueueOutput("myQueue")]
    public static IEnumerable<MyPocoType> Run([QueueTrigger("testqueue", Connection = "")] string myQueueItem,
        FunctionContext context)
    {
        var logger = context.GetLogger("testqueue");
        logger.LogInformation($"C# Queue trigger function processed: {myQueueItem}");

        return new List<MyPocoType>() {
            new MyPocoType()
            {
                Name = "Sun"
            },
            new MyPocoType()
            {
                  Name = "Mon"
            }
        };
    }
}

public class MyPocoType
{
    public string Name { get; set; }
}

To use the property output binding, we would need to make sure that the return type matches the type defined for the property. so it should look like --

public static class testqueue
{
    [Function("testqueue")]
    public static MyOutputType Run([QueueTrigger("testqueue", Connection = "")] string myQueueItem,
        FunctionContext context)
    {
        ...
    }
public class MyOutputType
{
    [QueueOutput("myQueue")]
    public IEnumerable<MyOtherPoco> Name { get; set; }
}

But, we agree that we may need to add analyzers to throw an error here. Thanks for reporting!!

fabiocav commented 3 years ago

Completely missed the attribute in your POCO, but as @ankitkumarr mentioned, we'll have some validation for this.