Skip to content

New serverless pattern - sam-dotnet-durablefunction-expenseapproval#3243

Open
dougperkes wants to merge 5 commits into
aws-samples:mainfrom
dougperkes:perkesdp-feature-sam-dotnet-durablefunction-expenseapproval
Open

New serverless pattern - sam-dotnet-durablefunction-expenseapproval#3243
dougperkes wants to merge 5 commits into
aws-samples:mainfrom
dougperkes:perkesdp-feature-sam-dotnet-durablefunction-expenseapproval

Conversation

@dougperkes

Copy link
Copy Markdown

Issue #, if available:

Description of changes: Lambda Durable Function — Expense Approval with Human Interaction (.NET)

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Comment thread sam-dotnet-durablefunction-expenseapproval/template.yaml
Comment thread sam-dotnet-durablefunction-expenseapproval/README.md Outdated
Comment thread sam-dotnet-durablefunction-expenseapproval/README.md Outdated
Comment thread sam-dotnet-durablefunction-expenseapproval/README.md Outdated
@bfreiberg

Copy link
Copy Markdown
Contributor

Code review findings

A few correctness issues and a doc mismatch in the new sam-dotnet-durablefunction-expenseapproval pattern:

1. src/ExpenseRepository.cs:51 — NRE on not-found lookup under AWS SDK v4

GetCallbackIdAsync dereferences response.Item without a null check. The project pins AWSSDK.DynamoDBv2 4.0.101.1, where GetItemResponse.Item is null (not an empty dict) when the key isn't found. So a POST /expenses/UNKNOWN-ID/approve throws NullReferenceException and the approver returns HTTP 500 instead of the intended 404 "not found or already processed".

2. src/ExpenseRepository.cs:22 — unvalidated optional fields → S=null → PutItem fails, step retries forever

SaveExpenseAsync sets AttributeValue { S = expense.SubmittedBy/Description/Currency/ManagerEmail } for fields that are never validated. A submission missing any of them (e.g. {"ExpenseId":"EXP-1","Amount":10} — the starter only validates ExpenseId + Amount) sets S=null, DynamoDB PutItem throws ValidationException, and RetryStrategy.Default keeps retrying the doomed write — wedging the workflow with the expense stuck pending.

3. src/ApproverHandler.cs:84 — approver duplicates the status write the workflow owns (racy)

After sending the callback, the approver writes the DynamoDB status itself, but the resumed workflow independently writes the same status in its process-reimbursement / handle-rejection steps. This is a redundant, racing double-write. Since the workflow owns state transitions in the durable model, the approver's write is architecturally unnecessary and can record a decision the workflow hasn't actually committed.

4. src/ExpenseWorkflowHandler.cs:112reimbursementId generated but never persisted or observable

The process-reimbursement step generates a reimbursement ID and places it only in the returned ExpenseResult. But the workflow is invoked asynchronously (InvocationType.Event), so its APIGatewayProxyResponse is discarded, and UpdateStatusAsync never stores the ID. No client or table read can ever retrieve the reimbursement ID the workflow claims to have created.

5. README.md:115 — submit response doesn't match the code

The README states the submit endpoint "returns HTTP 200 with the execution ARN", but ExpenseStarterHandler returns HTTP 202 with a {message, expenseId, status} body and no execution ARN. The documented status-tracking flow can't be followed as written.

…racy approver status write, persist reimbursementId, and correct README response docs
@dougperkes

Copy link
Copy Markdown
Author

@bfreiberg - all requested changes have been addressed.

@bfreiberg bfreiberg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks for your contribution. Your pattern will be merged soon

@dougperkes

Copy link
Copy Markdown
Author

@bfreiberg The AWS .NET DevEx team released the Amazon.Lambda.DurableExecution 1.0.0 right after you approved the PR. I've updated the project dependencies and made some code adjustments to correct new build warnings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants