feat : Add health endpoint#175
Conversation
|
Note
|
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |
✅ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | The title 'feat : Add health endpoint' directly and clearly summarizes the main change—adding a health endpoint to the application. |
| Description check | ✅ Passed | The description is fully related to the changeset, providing context about the health endpoint's functionality, HTTP status codes, response formats, and visual examples of both API and UI modes. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
- Create PR with unit tests
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
PluginBuilder/HostedServices/DockerStartupHostedService.cs (1)
8-27: Consider moving startup state to the hosted service class.The startup state properties and helpers are placed on
DockerStartupExceptionrather thanDockerStartupHostedService, unlike theDatabaseandAzurehosted services which keep their state directly on the service class. This creates an inconsistency and reduces cohesion (the exception class shouldn't own startup state).♻️ Suggested refactor
Move the static properties and methods from
DockerStartupExceptiontoDockerStartupHostedService:public class DockerStartupException : Exception { public DockerStartupException(string message) : base(message) { } - - public static bool DockerStartupCompleted { get; private set; } - public static Exception? DockerStartupError { get; private set; } - - public static void ResetStartupState() - { - DockerStartupCompleted = false; - DockerStartupError = null; - } - - public static void MarkStartupCompleted() - { - DockerStartupCompleted = true; - } - - public static void MarkStartupFailed(Exception ex) - { - DockerStartupError = ex; - DockerStartupCompleted = false; - } } public class DockerStartupHostedService : IHostedService { + public static bool DockerStartupCompleted { get; private set; } + public static Exception? DockerStartupError { get; private set; } + // ... existing code, update method calls to use 'this' classThen update
HealthService.csto use:-using static PluginBuilder.HostedServices.DockerStartupException; +using static PluginBuilder.HostedServices.DockerStartupHostedService;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@PluginBuilder/HostedServices/DockerStartupHostedService.cs` around lines 8 - 27, Move the startup state static properties and helper methods (DockerStartupCompleted, DockerStartupError, ResetStartupState, MarkStartupCompleted, MarkStartupFailed) out of the DockerStartupException class and into the DockerStartupHostedService class; update any callers (e.g., HealthService) to reference DockerStartupHostedService.DockerStartupCompleted and DockerStartupHostedService.DockerStartupError instead of DockerStartupException, and remove the state members from DockerStartupException so it only represents an exception.PluginBuilder/Services/AzureStorageClient.cs (1)
65-79: Pass the cancellation token from the health check.The
IsDefaultContainerAccessiblemethod correctly implements a timeout via linkedCancellationTokenSource, but the caller inHealthService(line 34) doesn't pass thecancellationToken. If the health check is cancelled, the Azure probe will continue running until its 15-second timeout.♻️ Proposed fix
In
PluginBuilder/Services/HealthService.cs, update line 34:-var azureTask = AzureStorageClient.IsDefaultContainerAccessible(); +var azureTask = AzureStorageClient.IsDefaultContainerAccessible(cancellationToken);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@PluginBuilder/Services/AzureStorageClient.cs` around lines 65 - 79, The health-check cancellation isn't propagated: update the caller in HealthService so it passes its CancellationToken into AzureStorageClient.IsDefaultContainerAccessible(cancellationToken) instead of calling it without parameters; this ensures the linked CancellationTokenSource timeout is preempted when the health check is cancelled. Locate the call to IsDefaultContainerAccessible in HealthService and forward the existing cancellationToken parameter to that method.PluginBuilder/Services/HealthService.cs (1)
60-77: Remove unusedOutputCaptureinstances.The
OutputCaptureobjects capture output that is never read. While the overhead is minimal, removing them simplifies the code.♻️ Proposed fix
private async Task<bool> IsDockerHealthy(CancellationToken cancellationToken) { try { var code = await ProcessRunner.RunAsync(new ProcessSpec { Executable = "docker", - Arguments = ["info", "--format", "{{ .ServerVersion }}"], - OutputCapture = new OutputCapture(), - ErrorCapture = new OutputCapture() + Arguments = ["info", "--format", "{{ .ServerVersion }}"] }, cancellationToken); return code == 0; } catch { return false; } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@PluginBuilder/Services/HealthService.cs` around lines 60 - 77, The IsDockerHealthy method is passing unused OutputCapture instances into ProcessSpec; remove those unused captures by omitting the OutputCapture and ErrorCapture properties when constructing the ProcessSpec passed to ProcessRunner.RunAsync (or set them to null if the type requires it) so ProcessSpec only includes Executable and Arguments; keep the rest of the logic (ProcessRunner.RunAsync call, arguments, cancellationToken check and return code comparison) unchanged.PluginBuilder/Views/Home/HealthPage.cshtml (1)
55-58: Redundant@prefix inside Razor code block.Inside the
@if (...)code block, you don't need the@prefix to referenceModel.Description. This works but is non-idiomatic.✨ Suggested fix
- `@if` (!string.IsNullOrWhiteSpace(`@Model.Description`)) + `@if` (!string.IsNullOrWhiteSpace(Model.Description)) { <p>Error: <code>@Model.Description</code></p> }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@PluginBuilder/Views/Home/HealthPage.cshtml` around lines 55 - 58, The Razor view uses a redundant '@' before Model.Description inside the `@if` (...) code block; remove the extra '@' so the line reads <p>Error: <code>@Model.Description</code></p> only using @ once to render the value, i.e., change the reference inside the block from `@Model.Description` to Model.Description while keeping the outer @ on the <code> element; update the HealthPage.cshtml `@if` block accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@PluginBuilder/Controllers/HomeController.cs`:
- Around line 806-820: The health response maps report.Status to result.status
using HealthStatus.Healthy only, but the HTTP response checks only
HealthStatus.Unhealthy, causing Degraded to yield body status "DOWN" with HTTP
200; update the logic so mapping and HTTP code align: change the status
assignment (result.status) to explicitly handle HealthStatus.Degraded (e.g., map
Degraded to "DOWN" or "UP" per desired policy) and update the response decision
(the conditional that returns StatusCode(...) vs Ok(...)) to treat
HealthStatus.Degraded the same as whichever payload status you choose; refer to
the variables result.status and report.Status and the return that currently
checks HealthStatus.Unhealthy to make the two consistent.
---
Nitpick comments:
In `@PluginBuilder/HostedServices/DockerStartupHostedService.cs`:
- Around line 8-27: Move the startup state static properties and helper methods
(DockerStartupCompleted, DockerStartupError, ResetStartupState,
MarkStartupCompleted, MarkStartupFailed) out of the DockerStartupException class
and into the DockerStartupHostedService class; update any callers (e.g.,
HealthService) to reference DockerStartupHostedService.DockerStartupCompleted
and DockerStartupHostedService.DockerStartupError instead of
DockerStartupException, and remove the state members from DockerStartupException
so it only represents an exception.
In `@PluginBuilder/Services/AzureStorageClient.cs`:
- Around line 65-79: The health-check cancellation isn't propagated: update the
caller in HealthService so it passes its CancellationToken into
AzureStorageClient.IsDefaultContainerAccessible(cancellationToken) instead of
calling it without parameters; this ensures the linked CancellationTokenSource
timeout is preempted when the health check is cancelled. Locate the call to
IsDefaultContainerAccessible in HealthService and forward the existing
cancellationToken parameter to that method.
In `@PluginBuilder/Services/HealthService.cs`:
- Around line 60-77: The IsDockerHealthy method is passing unused OutputCapture
instances into ProcessSpec; remove those unused captures by omitting the
OutputCapture and ErrorCapture properties when constructing the ProcessSpec
passed to ProcessRunner.RunAsync (or set them to null if the type requires it)
so ProcessSpec only includes Executable and Arguments; keep the rest of the
logic (ProcessRunner.RunAsync call, arguments, cancellationToken check and
return code comparison) unchanged.
In `@PluginBuilder/Views/Home/HealthPage.cshtml`:
- Around line 55-58: The Razor view uses a redundant '@' before
Model.Description inside the `@if` (...) code block; remove the extra '@' so the
line reads <p>Error: <code>@Model.Description</code></p> only using @ once to
render the value, i.e., change the reference inside the block from
`@Model.Description` to Model.Description while keeping the outer @ on the <code>
element; update the HealthPage.cshtml `@if` block accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 79042ec3-a5b2-467b-bceb-9a92e1e8a322
⛔ Files ignored due to path filters (1)
PluginBuilder/wwwroot/img/healthpage/up-successkid.jpgis excluded by!**/*.jpg
📒 Files selected for processing (10)
PluginBuilder/Controllers/HomeController.csPluginBuilder/HostedServices/AzureStartupHostedService.csPluginBuilder/HostedServices/DatabaseStartupHostedService.csPluginBuilder/HostedServices/DockerStartupHostedService.csPluginBuilder/PluginBuilder.csprojPluginBuilder/Program.csPluginBuilder/Services/AzureStorageClient.csPluginBuilder/Services/HealthService.csPluginBuilder/ViewModels/Home/HealthCheckViewModel.csPluginBuilder/Views/Home/HealthPage.cshtml

Related to #163 .
Can be requested as an API (returns JSON) :
Or as a page (health page styled after BTCPay Server error pages) :
Do you want me to add health endpoint to tests ?
Looking forwards your feedback :)