Skip to content

LNK-4430: Data Acquisition - Handle 429 Status - #1378

Merged
nvmLantana merged 14 commits into
devfrom
nvm/LNK-4430_Handle429QueryCase
Jan 20, 2026
Merged

LNK-4430: Data Acquisition - Handle 429 Status#1378
nvmLantana merged 14 commits into
devfrom
nvm/LNK-4430_Handle429QueryCase

Conversation

@nvmLantana

@nvmLantana nvmLantana commented Jan 16, 2026

Copy link
Copy Markdown
Contributor

🛠️ Description of Changes

The changes implement robust handling for HTTP 429 (Too Many Requests) responses in the Data Acquisition service, adhering to RFC 6585 by respecting the Retry-After header or falling back to exponential backoff. This includes detecting 429 in FHIR API calls, propagating a custom exception, and applying retry logic with delays in log processing. Additionally, prioritization ensures ACH-Daily queries (set to High priority) process before ACH-Monthly (Normal priority) via updated query ordering. Retries are capped at 5 (increased from 1), and logs are rescheduled by resetting ExecutionDate and Status to Pending. A shared utility class handles header capture for consistency. These enhancements prevent server overload, prioritize critical daily reports, and minimize data loss from rate limiting, with minimal impact on existing code.
Per Class/File Summary

TooManyRequestsException.cs (New File):
Added a custom exception inheriting from FhirOperationException to encapsulate 429 errors, including an optional RetryAfter TimeSpan property for delay information.

FhirCommandUtils.cs (New File):
Introduced a shared utility class containing the HeaderCapturingHandler (a DelegatingHandler to capture HTTP response headers) and the static ParseRetryAfter method to extract and parse the Retry-After header into a TimeSpan.

ReadFhirCommand.cs (Modified):
Integrated HeaderCapturingHandler to wrap the HttpClient for header capture. In ExecuteAsync, catch FhirOperationException for 429, parse Retry-After using the utility, and throw TooManyRequestsException. Used a new HttpClientHandler as the inner handler for the chain.

SearchFhirCommand.cs (Modified):
Similar to ReadFhirCommand.cs: Added HeaderCapturingHandler integration in ExecuteAsync and ExecuteNonPagingAsync. Catch 429 in search and paging operations, parse Retry-After, and throw TooManyRequestsException. Applied to initial search, paging continuation, and non-paging methods.

PatientDataService.cs (Modified):
In ExecuteLogRequest, added catch for TooManyRequestsException: Increment RetryAttempts, calculate delay (using RetryAfter or exponential backoff capped at 60s), reset ExecutionDate and Status to Pending, update log notes, and return to requeue. If retries exceed max, set Failed. In CreateLogEntries, set Priority to High for "Daily" reports, Normal otherwise.

DataAcquisitionLog.cs (Modified):
Increased MaxRetryAttempts constant from 1 to 5 to allow more retries before permanent failure.

FhirApiService.cs (Modified):
Added catches in ExecuteRead and ExecutePagingSearch to propagate TooManyRequestsException while handling other FhirOperationException as before (e.g., ignoring NotFound for references).

DataAcquisitionLogQueries.cs (Modified):
Updated GetNextEligibleBatchForFacility query. Added a filter to only include logs who either have a null execution date, or their execution date is present or past.

🧪 Testing Performed

Please describe the testing that was performed on the changes included in this PR.

🧑‍🔬 Unit Testing

  • I have written or updated unit tests to cover my changes

📓 Documentation Updated

Please update any relevant sections in the project documentation that were impacted by the changes in the PR.

Summary by CodeRabbit

  • New Features

    • Added rate-limiting (429) response handling with automatic retry-after support
    • Introduced intelligent retry mechanism with exponential backoff (up to 60 seconds)
    • Implemented dynamic priority assignment for daily reports
  • Improvements

    • Increased max retry attempts from 1 to 5 for better resilience
    • Enhanced batch eligibility logic to include retry-limited failed items
    • Added retry delay calculation based on attempt count or server-provided retry-after headers

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 16, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This pull request implements HTTP 429 (Too Many Requests) handling in the data acquisition service. It introduces a new exception type, HTTP header capture utilities, retry logic with exponential backoff, priority-based batch ordering, and increases maximum retry attempts from 1 to 5 across the FHIR API command pipeline and request orchestration layer.

Changes

Cohort / File(s) Summary
Exception Handling
DotNet/DataAcquisition.Domain/Application/Models/Exceptions/TooManyRequestsException.cs
New exception class derived from FhirOperationException with HTTP 429 status code, includes optional RetryAfter property (TimeSpan?) to convey retry timing from server.
HTTP Utilities
DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/FhirCommandUtils.cs
New utility module with HeaderCapturingHandler (DelegatingHandler to capture response headers) and ParseRetryAfter helper to parse Retry-After header as TimeSpan or HTTP-date.
FHIR Commands
DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/ReadFhirCommand.cs, DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/SearchFhirCommand.cs
Introduce HeaderCapturingHandler wrapping chain for HttpClient, add try-catch blocks to convert FhirOperationException with 429 status to TooManyRequestsException with parsed retry-after from captured headers. SearchFhirCommand handles 429 in both paging and non-paging paths.
FHIR API Service
DotNet/DataAcquisition.Domain/Application/Services/FhirApi/FhirApiService.cs
Add catch blocks for TooManyRequestsException in read and paging search paths to propagate exception upward.
Data Acquisition Service
DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs
Implement 429 throttling handler with retry logic: catch TooManyRequestsException, compute exponential backoff (floor 2^attempt, max 60s or RetryAfter if provided), defer execution, increment retry count. Add dynamic priority assignment (High for Daily reports, Normal otherwise). Update log state persistence on retry/failure paths.
Query & Entity Updates
DotNet/DataAcquisition.Domain/Application/Queries/DataAcquisitionLogQueries.cs, DotNet/DataAcquisition.Domain/Infrastructure/Entities/DataAcquisitionLog.cs
Expand GetNextEligibleBatchForFacility to include failed logs with RetryAttempts < MaxRetryAttempts; add multi-criteria ordering (Priority DESC, ExecutionDate ASC, Id ASC). Increase MaxRetryAttempts constant from 1 to 5.

Sequence Diagram(s)

sequenceDiagram
    participant Client as PatientDataService
    participant Cmd as FHIR Command<br/>(Read/Search)
    participant Handler as HeaderCapturing<br/>Handler
    participant FhirServer as FHIR Server
    participant DB as Database

    Client->>Cmd: ExecuteAsync(request)
    Cmd->>Handler: Create HttpClient with handler
    Handler->>FhirServer: HTTP Request
    FhirServer-->>Handler: 429 Too Many Requests<br/>+ Retry-After header
    Handler->>Handler: Capture response headers
    Cmd->>Cmd: Detect TooManyRequests
    Cmd->>Cmd: Parse Retry-After header<br/>via ParseRetryAfter()
    Cmd-->>Client: Throw TooManyRequestsException<br/>with RetryAfter value
    
    Client->>Client: Catch TooManyRequestsException
    Client->>Client: Calculate backoff delay<br/>max(2^attempt, RetryAfter, 60s)
    Client->>DB: Update log:<br/>Status=Pending<br/>ExecutionDate=now+delay<br/>RetryAttempts++
    Client->>DB: Re-queue for later<br/>execution
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • edward-miller-lcg
  • arianamihailescu

Poem

🐰 Too many requests? The bunny hops back,
With Retry-After headers and backoff on track,
Exponential delays, a patient refrain,
429 throttling won't cause us pain—
Resourceful retries save the day again! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: handling HTTP 429 status codes in data acquisition, directly matching the pull request's primary objective.
Linked Issues check ✅ Passed The changes comprehensively address LNK-4430 objectives: detect 429 responses, implement retry/throttling with exponential backoff, reset execution dates, use Priority field for daily/monthly prioritization, and capture retry-after headers.
Out of Scope Changes check ✅ Passed All changes are directly scoped to 429 handling implementation: new exception class, retry logic, header parsing, command updates, and data service enhancements—no unrelated modifications detected.
Description check ✅ Passed The PR description provides a comprehensive overview of changes across all modified and new files, with detailed per-file summaries explaining the implementation of 429 handling and prioritization logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In
`@DotNet/DataAcquisition.Domain/Application/Queries/DataAcquisitionLogQueries.cs`:
- Around line 571-576: The query in DataAcquisitionLogQueries against
_dbContext.DataAcquisitionLogs must exclude logs scheduled for the future and
handle nullable RetryAttempts safely: add a where clause requiring
(log.ExecutionDate == null || log.ExecutionDate <= DateTime.UtcNow) and change
the retry check to coalesce RetryAttempts to zero (e.g., (log.RetryAttempts ??
0) < DataAcquisitionLog.MaxRetryAttempts) so only executable logs are returned
and null comparisons are safe.

In
`@DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/FhirCommandUtils.cs`:
- Around line 19-30: The ParseRetryAfter(HttpResponseHeaders? headers) method
can return negative TimeSpan values when the parsed HTTP-date is in the past;
clamp negative durations to TimeSpan.Zero (or return null consistently) instead
of returning a negative value—modify the branch that computes date -
DateTimeOffset.UtcNow to compute max(date - DateTimeOffset.UtcNow,
TimeSpan.Zero) (or return null if you prefer) and ensure the method still
handles null headers and integer-second parsing; then add XUnit tests covering:
null headers, integer seconds parse, HTTP-date parse yielding a future duration,
and HTTP-date parse yielding a past date to assert clamping behavior for
ParseRetryAfter.

In
`@DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/ReadFhirCommand.cs`:
- Around line 65-70: The handler/HttpClient are being created per-request which
bypasses DI-configured settings and creates new connection pools; instead use
the DI-registered client/handler chain: obtain the FHIR HttpClient from the
injected _httpClient or via IHttpClientFactory (the named
"FhirHttpClient"/DI-registered HeaderCapturingHandler) and pass that instance
into the FhirClient constructor (FhirClient(..., httpClient, ...)) so you reuse
the DI pipeline and AutomaticDecompression configuration; if you cannot refactor
DI immediately, at minimum construct the per-request client from the injected
client's configuration (copy _httpClient.Timeout and DefaultRequestHeaders, and
ensure the underlying handler’s AutomaticDecompression is preserved) and dispose
handlers/clients properly, but prefer registering HeaderCapturingHandler as a
DelegatingHandler and using the DI-provided client for ReadFhirCommand.

In
`@DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/SearchFhirCommand.cs`:
- Around line 79-84: The new HttpClient, HttpClientHandler and
HeaderCapturingHandler created around HeaderCapturingHandler (var innerHandler =
new HttpClientHandler(); var headerCapturingHandler = new HeaderCapturingHandler
{ InnerHandler = innerHandler }; var httpClientWithHandler = new
HttpClient(headerCapturingHandler);) must be disposed to avoid socket
exhaustion: wrap creation and usage of HttpClientHandler, HeaderCapturingHandler
and HttpClient (and the resulting FhirClient instance if it implements
IDisposable) in using blocks (or obtain the HttpClient from IHttpClientFactory)
so all three objects are disposed after FhirClient is used (also apply the same
disposal around the second creation at lines ~165-170). Ensure you reference and
dispose HeaderCapturingHandler, innerHandler (HttpClientHandler),
httpClientWithHandler (HttpClient) and the created FhirClient.

In `@DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs`:
- Around line 548-582: The TooManyRequestsException handler in
PatientDataService (catch block shown) may use a negative ex.RetryAfter which
causes DateTime.UtcNow.Add(delay) to schedule immediate retries; clamp the
computed delay to a non‑negative TimeSpan (e.g., delay =
TimeSpan.Max(TimeSpan.Zero, delay)) before setting log.ExecutionDate and
log.Notes, keep existing exponential backoff fallback when ex.RetryAfter is
null, and preserve RetryAttempts/Status updates and the UpdateAsync call; then
add xUnit tests (using Moq to fake _dataAcquisitionLogManager and any other
deps) exercising: max retries exceeded branch, positive Retry-After branch, and
negative/ past Retry-After falling back to zero or exponential backoff, and
update the PR description to list the added tests and that no network calls are
performed.
🧹 Nitpick comments (4)
DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/FhirCommandUtils.cs (1)

19-31: Add XUnit coverage for Retry-After parsing branches.

Please add tests for: null headers, delta-seconds, HTTP-date, invalid value, and past-date cases. Use Moq/fakes—no network calls. As per coding guidelines, ensure each branch is covered.

DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/SearchFhirCommand.cs (1)

70-112: Add XUnit tests for validation and 429 mapping paths.

Please cover: invalid request (null/empty facilityId or base URL), SearchPost vs Search branches, and 429 mapping to TooManyRequestsException (including paging). Use Moq/fakes to avoid network activity. As per coding guidelines, ensure each branch is tested.

DotNet/DataAcquisition.Domain/Application/Services/FhirApi/FhirApiService.cs (1)

303-318: Add XUnit tests for InsertDateExtension branches.

Please cover: null resource, Meta initialization, Extension initialization, and “already present” cases. Keep tests small and mock external dependencies. As per coding guidelines, ensure each branch is tested.

DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs (1)

230-241: Confirm ReportTypes mapping and priority scope; add tests.

This only checks for exact "Daily" and only applies on the Initial path. If report types are stored as "ACH Daily"/"ACH Monthly" (or if supplemental logs should inherit the same priority), the intended prioritization may be skipped. Please confirm the expected values and scope, and add xUnit tests for both branches (Daily vs non‑Daily) using Moq (no network calls). As per coding guidelines, ensure each branch is covered by tests.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e76d56f and 717291c.

📒 Files selected for processing (8)
  • DotNet/DataAcquisition.Domain/Application/Models/Exceptions/TooManyRequestsException.cs
  • DotNet/DataAcquisition.Domain/Application/Queries/DataAcquisitionLogQueries.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/FhirCommandUtils.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/ReadFhirCommand.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/SearchFhirCommand.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/FhirApiService.cs
  • DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs
  • DotNet/DataAcquisition.Domain/Infrastructure/Entities/DataAcquisitionLog.cs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

⚙️ CodeRabbit configuration file

**/*.cs: The HtmlInputSanitizer class's Sanitize() and SanitizeAndRemove() methods should be used when dealing with string query parameters from REST requests.

Files:

  • DotNet/DataAcquisition.Domain/Infrastructure/Entities/DataAcquisitionLog.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/FhirApiService.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/SearchFhirCommand.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/FhirCommandUtils.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/ReadFhirCommand.cs
  • DotNet/DataAcquisition.Domain/Application/Models/Exceptions/TooManyRequestsException.cs
  • DotNet/DataAcquisition.Domain/Application/Queries/DataAcquisitionLogQueries.cs
  • DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs
**

⚙️ CodeRabbit configuration file

**: Pull requests that have "TECH_DEBT" in the title should only contain changes related to typos, unused code, linter/IDE suggestions, swagger specification updates,
and logging improvements. These TECH_DEBT PRs must not affect core functionality. All PRs that are not considered technical debt must include information on what
testing was performed in the description of the PR. If it does not, ask the author to provide details on what testing was performed.
When reviewing code, suggest unit tests using XUnit in the following scenarios:

  • If/Else or Switch/Case blocks are introduced or modified — ensure each branch has a corresponding unit test.
  • Logic that depends on service or interface configuration — suggest tests to validate different implementations are correctly resolved.
  • No network activity (HTTP calls, sockets, etc.) should appear in unit tests. Recommend using mocks (via Moq) for any external communication.
    Large unit tests should be avoided; keeping unit tests small and focused on targeted business logic (i.e. string sanitization)

**: Pull requests that have DOCS in the title should only contain changes related to documentation within the /docs folder or in .md files through-out the code-base. The description
of the PR should specify what documentation was updated. Documentation updates should use EventCatalog.dev structure, where service-specific functionality should be described
in the service's index.mdx (i.e. /services/XXX/index.mdx or /domains/XXX/services/YYY/index.mdx). Configurations that are shared by multiple services should be
reflected in the /docs/docs/config files.

Files:

  • DotNet/DataAcquisition.Domain/Infrastructure/Entities/DataAcquisitionLog.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/FhirApiService.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/SearchFhirCommand.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/FhirCommandUtils.cs
  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/ReadFhirCommand.cs
  • DotNet/DataAcquisition.Domain/Application/Models/Exceptions/TooManyRequestsException.cs
  • DotNet/DataAcquisition.Domain/Application/Queries/DataAcquisitionLogQueries.cs
  • DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs
🧠 Learnings (10)
📓 Common learnings
Learnt from: amphillipsLGC
Repo: lantanagroup/link-cloud PR: 434
File: DotNet/LinkAdmin.BFF/Application/Clients/NormalizationService.cs:21-37
Timestamp: 2024-08-13T18:39:37.249Z
Learning: In the Link Admin project, `HttpRequestException` for HTTP requests in service classes like `NormalizationService` is propagated to the health check layer, where it is handled.
📚 Learning: 2024-08-20T18:40:16.363Z
Learnt from: amphillipsLGC
Repo: lantanagroup/link-cloud PR: 437
File: DotNet/LinkAdmin.BFF/Application/Clients/DataAcquisitionService.cs:24-29
Timestamp: 2024-08-20T18:40:16.363Z
Learning: In the `DataAcquisitionService` class, exceptions in the `ServiceHealthCheck` method are handled at a higher level in the health check process, so additional exception handling within the method is unnecessary.

Applied to files:

  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/FhirApiService.cs
📚 Learning: 2024-08-20T18:40:08.081Z
Learnt from: amphillipsLGC
Repo: lantanagroup/link-cloud PR: 437
File: DotNet/LinkAdmin.BFF/Application/Clients/NormalizationService.cs:24-29
Timestamp: 2024-08-20T18:40:08.081Z
Learning: In the `NormalizationService` class, exceptions in the `ServiceHealthCheck` method are handled at a higher level in the health check process, so additional exception handling within the method is unnecessary.

Applied to files:

  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/FhirApiService.cs
📚 Learning: 2025-09-24T21:08:44.732Z
Learnt from: seanmcilvenna
Repo: lantanagroup/link-cloud PR: 669
File: DotNet/Terminology/Application/Formatters/FhirModelBinder.cs:1-8
Timestamp: 2025-09-24T21:08:44.732Z
Learning: In the FhirModelBinder.cs file (DotNet/Terminology/Application/Formatters/FhirModelBinder.cs), the implementation uses simple string comparison for content-type checking and direct stream reading without requiring additional usings like Microsoft.Net.Http.Headers or Microsoft.AspNetCore.Http beyond what's already imported. The code relies on implicit usings available in .NET 8 for basic types like StreamReader and ArgumentNullException.

Applied to files:

  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/FhirApiService.cs
📚 Learning: 2025-07-03T02:55:02.829Z
Learnt from: edward-miller-lcg
Repo: lantanagroup/link-cloud PR: 941
File: DotNet/DataAcquisition.Domain/Application/Services/ReferenceResourceService.cs:0-0
Timestamp: 2025-07-03T02:55:02.829Z
Learning: In ReferenceResourceService.ProcessReferences method, the refResources parameter can legitimately be null when the caller doesn't find any references to pass. This results in an early return with no processing, which is the intended behavior. The log parameter, however, should never be null and correctly throws an ArgumentNullException.

Applied to files:

  • DotNet/DataAcquisition.Domain/Application/Services/FhirApi/FhirApiService.cs
📚 Learning: 2025-10-06T17:27:23.535Z
Learnt from: edward-miller-lcg
Repo: lantanagroup/link-cloud PR: 1180
File: DotNet/Report/KafkaProducers/DataAcquisitionRequestedProducer.cs:51-0
Timestamp: 2025-10-06T17:27:23.535Z
Learning: In the Report service's DataAcquisitionRequestedProducer, the traceparent header should always use the pre-generated parent trace context IDs (the randomly generated traceId and spanId used to create the activityContext), not the started producer Activity's context. This pattern ensures each patient receives a unique trace ID while maintaining the intended trace propagation across services.

Applied to files:

  • DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs
📚 Learning: 2025-10-06T17:27:14.365Z
Learnt from: edward-miller-lcg
Repo: lantanagroup/link-cloud PR: 1180
File: DotNet/DataAcquisition/Jobs/AcquisitionProcessingJob.cs:239-279
Timestamp: 2025-10-06T17:27:14.365Z
Learning: In DataAcquisition.Jobs.AcquisitionProcessingJob's ProcessPendingTailingMessages method, when constructing the traceparent header for ResourceAcquired messages, always prioritize using message.TraceParentId if it exists to maintain trace continuity. Only fall back to the current activity's context when the persisted TraceParentId value is not available.

Applied to files:

  • DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs
📚 Learning: 2025-06-26T20:07:57.494Z
Learnt from: edward-miller-lcg
Repo: lantanagroup/link-cloud PR: 929
File: DotNet/DataAcquisitionTests/ServiceTests/PatientDataServiceTests.cs:337-454
Timestamp: 2025-06-26T20:07:57.494Z
Learning: In the `CreateLogEntries` method of `PatientDataService`, when `IQueryListProcessor.Process` throws a `ProduceException<string, ResourceAcquired>`, the exception is rethrown directly without being wrapped in a `TransientException`. The test should validate the original `ProduceException` being thrown.

Applied to files:

  • DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs
📚 Learning: 2026-01-13T02:00:48.044Z
Learnt from: seanmcilvenna
Repo: lantanagroup/link-cloud PR: 1368
File: DotNet/DataAcquisition.Domain/Application/Factories/ParameterFactories/VariableParameterFactory.cs:15-19
Timestamp: 2026-01-13T02:00:48.044Z
Learning: In the DataAcquisition.Domain project, parameter factories (LiteralParameterFactory, VariableParameterFactory, ResourceIdParameterFactory) are being converted from static classes to services that support dependency injection, allowing proper ILogger injection instead of static LoggerFactory creation patterns.

Applied to files:

  • DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs
📚 Learning: 2025-08-05T20:07:18.492Z
Learnt from: smailliwcs
Repo: lantanagroup/link-cloud PR: 968
File: DotNet/Report/KafkaProducers/ReportManifestProducer.cs:144-145
Timestamp: 2025-08-05T20:07:18.492Z
Learning: Patient ID extraction logic in the Link Cloud codebase will be refactored in the future using ResourceIdentity for ID parsing, as mentioned by smailliwcs. This will provide a more systematic and consistent approach to handling FHIR resource identifiers across the codebase.

Applied to files:

  • DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs
🧬 Code graph analysis (5)
DotNet/DataAcquisition.Domain/Application/Services/FhirApi/FhirApiService.cs (2)
DotNet/DataAcquisition.Domain/Application/Models/Exceptions/TooManyRequestsException.cs (2)
  • TooManyRequestsException (6-13)
  • TooManyRequestsException (9-12)
DotNet/DataAcquisition.Domain/Settings/DataAcquisitionConstants.cs (2)
  • Extension (20-23)
  • DataAcquisitionConstants (4-46)
DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/SearchFhirCommand.cs (2)
DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/FhirCommandUtils.cs (2)
  • HeaderCapturingHandler (5-15)
  • FhirCommandUtils (17-33)
DotNet/DataAcquisition.Domain/Application/Models/Exceptions/TooManyRequestsException.cs (2)
  • TooManyRequestsException (6-13)
  • TooManyRequestsException (9-12)
DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/ReadFhirCommand.cs (3)
DotNet/DataAcquisition.Domain/Settings/DataAcquisitionConstants.cs (1)
  • Auth (40-45)
DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/FhirCommandUtils.cs (2)
  • HeaderCapturingHandler (5-15)
  • FhirCommandUtils (17-33)
DotNet/DataAcquisition.Domain/Application/Models/Exceptions/TooManyRequestsException.cs (2)
  • TooManyRequestsException (6-13)
  • TooManyRequestsException (9-12)
DotNet/DataAcquisition.Domain/Application/Models/Exceptions/TooManyRequestsException.cs (1)
DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/FhirCommandUtils.cs (1)
  • TimeSpan (19-32)
DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs (3)
DotNet/DataAcquisition.Domain/Application/Models/Exceptions/TooManyRequestsException.cs (2)
  • TooManyRequestsException (6-13)
  • TooManyRequestsException (9-12)
DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/FhirCommandUtils.cs (1)
  • TimeSpan (19-32)
DotNet/DataAcquisition.Domain/Application/Models/Api/QueryLog/UpdateDataAcquisitionLogModel.cs (1)
  • UpdateDataAcquisitionLogModel (7-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Integration Tests
  • GitHub Check: Smoke Test with Docker Compose
  • GitHub Check: Unit Tests for DotNet
  • GitHub Check: Build Documentation
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Analyze (java-kotlin)
🔇 Additional comments (4)
DotNet/DataAcquisition.Domain/Infrastructure/Entities/DataAcquisitionLog.cs (1)

12-12: Please add testing details to the PR description.

The PR description has placeholders but no testing info. Please list tests run (unit/integration) or explicitly state if none were run. As per coding guidelines, please provide this detail.

DotNet/DataAcquisition.Domain/Application/Services/FhirApi/Commands/ReadFhirCommand.cs (1)

88-97: Clean 429 translation with Retry-After propagation.

The conversion to TooManyRequestsException with parsed Retry-After is solid and matches the new throttling flow.

DotNet/DataAcquisition.Domain/Application/Services/PatientDataService.cs (2)

413-448: Good: trace and completion timing preserved on updates.

Keeping CompletionTimeMilliseconds and TraceId in these update paths avoids losing observability data.

Also applies to: 535-546, 592-599


466-523: LGTM on skipFetch guard and _id parsing.

No concerns with the guard or the ID extraction flow.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread DotNet/DataAcquisition.Domain/Application/Queries/DataAcquisitionLogQueries.cs Outdated
@nvmLantana
nvmLantana requested a review from smailliwcs January 16, 2026 22:00

@smailliwcs smailliwcs 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.

IIUC, this makes it so that, if we receive an HTTP 429, we defer the current DA log in a way that respects the Retry-After header. Don't we need something that defers all DA logs (for the current tenant)?

@nvmLantana
nvmLantana merged commit 3db02ac into dev Jan 20, 2026
19 checks passed
@nvmLantana
nvmLantana deleted the nvm/LNK-4430_Handle429QueryCase branch January 20, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants