Azure / azure-functions-dotnet-worker

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

ServiceBusTrigger breakpoints not working because I forgot to add ConfigureFunctionsWorkerDefaults() in host builder. #1347

Open davidpetric opened 1 year ago

davidpetric commented 1 year ago

Hi all,

I had a really strange issue today with ServiceBusTrigger.

Spent like 4 hours in total confusion because was not understanding why it was working and now it doesn't and no errors at compile time or run time.

I was experimenting with some ideas to try and create subscriptions for topics programmatically before the azure function is bootstrapped/initialized and somehow I deleted the ConfigureFunctionsWorkerDefaults() from the Program.cs file.

No errors no exceptions, no warnings. Even the ServiceBus messages looked like arriving but the function won't process either the breakpoints could not be loaded(but vs won't complain that it could not load the module) and the azure function did not want to trigger to process the message and complete it. I tried everything that I could've to think of until I thought of creating a new project of isolated azure function and compared what was different.

The logs looked something like this:

[2023-02-14T15:14:46.966Z] Executing 'Functions.ActivityTopicServiceBusTrigger' (Reason='(null)', Id=bdc7431b-72b6-48f6-a8d5-09a7dbe86862)
[2023-02-14T15:14:46.968Z] Trigger Details: MessageId: d32842a121b14ddc81671ae1e9a4c7de, SequenceNumber: 3, DeliveryCount: 11, EnqueuedTimeUtc: 2023-02-14T14:58:46.5010000+00:00, LockedUntilUtc: 2023-02-14T15:15:36.7900000+00:00, SessionId: (null)

my .csproj looks like this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>disable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="AutoMapper" Version="12.0.0" />
    <PackageReference Include="Azure.Messaging.ServiceBus" Version="7.12.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.10.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Core" Version="1.8.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Abstractions" Version="1.1.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.ServiceBus" Version="5.7.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.7.0" />
  </ItemGroup>

Azure Function:

    [Function("ActivityTopicServiceBusTrigger")]
    public void ActivityTopicServiceBusTrigger(
        [ServiceBusTrigger(
            topicName: "Activity",
            subscriptionName: "mySub",
            Connection =  "ServiceBusConnectionString"
        )]
            string message,
            string subject,
            FunctionContext context)
    {
        this.HandleMessage(subject, message);
    }

My Program.cs

public static class Program
{
    public static async Task Main()
    {
        ServiceBusAdminClient serviceBusAdmin = new(new ServiceBusAdministrationClient(Env.GetEnvironmentNotNullVariable(Constants.ServiceBusConnectionString)));
        await serviceBusAdmin.CreateOrUpdateAzureServiceBusSubscriptionsAsync();

        IHost host = new HostBuilder()
            .ConfigureFunctionsWorkerDefaults()
            .ConfigureAppConfiguration(builder =>
            {
                builder.SetBasePath(Directory.GetCurrentDirectory())
                        .AddJsonFile("local.settings.json", true, true)
                        .AddUserSecrets(Assembly.GetExecutingAssembly(), true)
                        .AddEnvironmentVariables();
            })
            .ConfigureServices((_, services) =>
            {
                services.AddLogging();

                services.Configure<JsonSerializerOptions>(options =>
                {
                    options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
                    options.Converters.Add(new JsonStringEnumConverter());
                });
            })
            .Build();

        host.Run();
    }

So by adding.ConfigureFunctionsWorkerDefaults() to HostBuilder I solved my issue.

Hope this helps someone to not waste time as I did.

jviau commented 1 year ago

No errors no exceptions, no warnings.

This is expected. Without ConfigureFunctionsWorkerDefaults() there is no functions code running in your worker to even report errors, warnings, or throw exceptions. You still see service bus messages because the function trigger metadata was collected as part of the build and loaded by the host process. The host is still behaving as expected.

@fabiocav would you expect the host to detect no worker / incorrectly configured worker and report errors here? My gut would tell me no and that it isn't possible to do correctly. How do you tell the difference between an incorrectly configured worker and one just slow to start up?

SeanFeldman commented 1 year ago

@jviau, would a code analyzer help in this scenario? It could throw an error to the end-user and elaborate on what's missing.

davidpetric commented 1 year ago

How should have I known that it was expected behavior? An error would help a lot from my point of view, even a warning message somewhere in docs.

fabiocav commented 1 year ago

@davidpetric can you confirm you didn't see any exceptions when the host/Core Tools initialized? I would expect to see errors indicating a worker initialization failure, as without that call, the worker would never connect and register with the host.

Flagging this so we can repro/investigate the behavior and identify enhancements we can make to improve this.

davidpetric commented 1 year ago

@fabiocav I can confirm, I've tested on my personal pc and work pc.

Example of a project with commented ConfigureFunctionsWorkerDefaults() in Program.cs, A ServiceBusTrigger function, and sending messages from Azure Portal which are logged into the console as I send them but breakpoints aren't hit in VS and errors don't show up anywhere: az_func

My personal pc VS studio version : image

and Azure function: image

A repro project(need to have a valid ServiceBus connection string with a topic name 'mytopic' and subscription name 'mysubscription', writing this so anyone who will download will know why they have lots of errors with 404 in console): ReproFunction.zip

SeanFeldman commented 1 year ago

@fabiocav, ironically, this also happened to me. The only way I figured out something was off is by not being able to bind some of the custom settings to strongly typed settings object. The repro is simple - having a function app that contains just a Service Bus trigger. No exceptions, no errors, nothing.

My recommendation save me a couple of hours of troubleshooting.

Bit-Shifts commented 5 months ago

@davidpetric I seen the exact same thing that you seen but with a twist.

I had called both on my HostBuilder in my Program.cs file

.ConfigureFunctionsWebApplication()and .ConfigureFunctionsWorkerDefaults()

TeoChirileanu commented 5 months ago

+1, this has happened to me as well spent countless hours finding it