I'm trying to wrap my head around how to manage controlled and uncontrolled results/failures in Azure Functions triggered by Event Grid events. I'm sure I'm missing some fundamental aspect but I can't really make sense of the available Microsoft documentation.
Using the current Visual Studio 2019 Azure Function templates for Event Grid triggers, we get C# methods that looks similar to this:
[FunctionName("UserCreated")]
public static void UserCreated([EventGridTrigger]EventGridEvent evt, ILogger log)
{
...
}
Q1. What is the proper way of returning statuses and error codes from these methods so that the event can be either retried or passed to the dead letter blob? Lets say I want to return a Status 400 Bad Request because the custom data payload in the event that was passed in wasn't up to speed. I've tried this:
[FunctionName("UserCreated")]
public static async Task<IActionResult> UserCreated([EventGridTrigger]EventGridEvent evt, ILogger log)
{
...
return new BadRequestObjectResult("ouch");
}
... which just results in this error when running the function locally:
Cannot bind parameter '$return' to type IActionResult&. Make sure the parameter Type is supported by the binding.
I don't understand this error and have no idea how to solve it.
Q2. How do we properly catch exceptions and return them in an orderly fashion? Let's say the UserCreated method above requires the passed in event to have a few custom datapoints, and that one of those datapoints are missing. E.g. we have this:
[JsonObject(ItemRequired = Required.Always)]
private class CustomerAndContactIds
{
public int CustomerId { get; set; }
public int ContactId { get; set; }
}
... and when we convert some event data that is missing e.g. the ContactID field, like so:
private static T ExtractCustomPayloadFromEvent<T>(EventGridEvent evt)
{
return JObject.FromObject(evt.Data).ToObject<T>();
}
... we get this in the logs:
System.Private.CoreLib: Exception while executing function: UserCreated. Newtonsoft.Json: Required property 'ContactPersonId' not found in JSON. Path ''.
However, all we get in e.g. Postman is:
Exception while executing function: UserCreated
What's the proper way of making this a bit more legible for consumers that aren't privy to e.g. the Azure log stream or Azure Insights?