Pass ServiceBusReceivedMessage through ProcessAsync end-to-end#20
Merged
Conversation
Previous refactor stopped at the function boundary: Run took the
message, then immediately unrolled it into a flat parameter list
(string body, string? messageId, int deliveryCount, ...) before
handing to ProcessAsync. That meant the "real" work never had the
message in hand — same anti-pattern in both functions.
Both `ProcessAsync` methods now take `ServiceBusReceivedMessage`
directly and read every field off it. Body is deserialised via
`message.Body.ToObjectFromJson<T>()` instead of going through the
extension's string binding.
Tests construct real `ServiceBusReceivedMessage` instances via
`ServiceBusModelFactory.ServiceBusReceivedMessage(...)`. Two small
notes:
- The factory doesn't expose `deadLetterReason` /
`deadLetterErrorDescription` as direct parameters — those
properties on the message are surfaced from broker properties
with those exact keys, so the DLQ helper sets them via the
`properties` dictionary.
- `BinaryData.FromString("")` produces a state where `.ToString()`
throws `ArgumentNullException`. Guard in the DLQ handler so
zero-length bodies don't crash.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The previous refactor only got halfway:
Runtook theServiceBusReceivedMessage, then immediately unrolled it into a flat parameter list (string body, string? messageId, int deliveryCount, ...) before callingProcessAsync. The actual work still operated on astring. Same anti-pattern in both functions.This PR fixes that. Both
ProcessAsyncmethods now takeServiceBusReceivedMessagedirectly and read every field off the message. Body is deserialised viamessage.Body.ToObjectFromJson<SharePointListUpdatedEvent>()instead of through the trigger's string binding.Test notes
Tests now construct real messages via
ServiceBusModelFactory.ServiceBusReceivedMessage(...). Two quirks discovered along the way:deadLetterReason/deadLetterErrorDescriptionas direct parameters. Those properties onServiceBusReceivedMessageare surfaced from broker-side properties with those exact keys, so the DLQ test helper sets them via thepropertiesdictionary.BinaryData.FromString("")produces a state where.ToString()throwsArgumentNullException. Guard added in the DLQ handler so a zero-byte body returns""instead of crashing.Test plan
dotnet build— clean.dotnet format --verify-no-changes— clean.dotnet test tests/Function.Tests— 13/13 pass.function-appworkflow ships the new binding. Spot-check a live publisher run still emitsDocumentPublishedwithMessageId,DeliveryCount, andenqueueLatencyMson the event.🤖 Generated with Claude Code