Skip to content

chore(analyzer): clear the warnings from the SonarAnalyzer 10.31 bump - #307

Open
rlorenzo wants to merge 6 commits into
mainfrom
chore/sonar-1031-warnings
Open

chore(analyzer): clear the warnings from the SonarAnalyzer 10.31 bump#307
rlorenzo wants to merge 6 commits into
mainfrom
chore/sonar-1031-warnings

Conversation

@rlorenzo

@rlorenzo rlorenzo commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Closes 58 of the 59 warnings added by the SonarAnalyzer 10.31 bump. Build goes from 79 warnings to 21.

One commit per rule family; the file sets are disjoint, so any single commit can be dropped independently.

Rule Sites Change
S8969 41 Remove redundant null-forgiving operators
S8949 7 Pass context.RequestAborted; explicit CancellationToken.None on the two SSE Task.Run calls
S2971 5 Fold Where(...).Any() into Any(...)
S2077, S5332, S4502, S4790 4 Suppress with justifications: parameter placeholders bound via AddWithValue, XML namespace literal, anonymous error page, legacy uInform HMACSHA1
S6444 1 Bound the CMS download-name regex to 1s, treating a timeout as an unsafe name

Behavioural changes, worth a closer look:

  • ViteProxyHelpers and SitemapMiddleware now catch OperationCanceledException when (context.RequestAborted.IsCancellationRequested). Without it a client disconnect read as a Vite outage or a sitemap failure, and fell through to further middleware on an already-started response.
  • The two clinical-import commit guards move from if (ownsTransaction) to if (transaction != null): equivalent by construction, but provable to the compiler.
  • AddInstructor and SetPrimaryEvaluator capture their [Required] nullable fields into non-null locals behind an explicit guard, clearing the CodeQL nullable-dereference findings on those lines.

Not fixed: S1313, the hardcoded F5 internal IP in ForwardedHeadersExtensions. Moving it to config beside the Cloudflare CIDRs is proxy-trust surface and belongs with the Program.cs work.

Verified: clean-cache npm run verify:build 79 to 21 warnings, zero CS diagnostics; npm run test:backend 2708 passed.

- treat a timed-out match as an unsafe name and fall back to the default,
  matching the fail-safe path every other rejection in the method takes
- S2077: the interpolated SQL carries only the generated @jc parameter
  placeholders; every job code binds through AddWithValue
- S5332: the CAS literal is an XML namespace identifier, not an endpoint
- S4502: the error page is anonymous, binds one route int, mutates nothing
- S4790: widen the existing CA5350 disable to Sonar's equivalent rule
Completes c5e5eef, which folded the First/FirstOrDefault shapes and left
every Any shape behind. All five receivers are EF DbSets, so the generated
SQL is unchanged.
- pass context.RequestAborted to the sitemap writes, the Vite proxy body
  copy, the static-file fallback and the 502 body, so work stops when the
  client disconnects instead of running to completion
- opt the two SSE Task.Run calls out explicitly with CancellationToken.None:
  a token there only prevents the task starting, which would skip the
  lambda catch and leave the channel un-completed
@codecov-commenter

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

@codecov-commenter

codecov-commenter commented Aug 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 26.66667% with 55 lines in your changes missing coverage. Please review.
✅ Project coverage is 41.86%. Comparing base (394ae2d) to head (f086392).

Files with missing lines Patch % Lines
...eduler/Controllers/InstructorScheduleController.cs 40.00% 14 Missing and 1 partial ⚠️
web/Areas/Students/Services/StudentList.cs 0.00% 8 Missing ⚠️
web/ViteProxyHelpers.cs 0.00% 8 Missing ⚠️
web/Classes/SitemapMiddleware.cs 0.00% 5 Missing ⚠️
...CTS/Controllers/BundleCompetencyGroupController.cs 0.00% 4 Missing ⚠️
web/Areas/CMS/Services/CmsFilePathSafety.cs 62.50% 3 Missing ⚠️
...reas/CTS/Controllers/BundleCompetencyController.cs 0.00% 2 Missing ⚠️
web/Areas/Effort/Services/ClinicalImportService.cs 66.66% 2 Missing ⚠️
...Areas/Effort/Services/Harvest/CrestHarvestPhase.cs 0.00% 2 Missing ⚠️
...nicalScheduler/Controllers/CliniciansController.cs 0.00% 1 Missing ⚠️
... and 5 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #307      +/-   ##
==========================================
- Coverage   41.88%   41.86%   -0.02%     
==========================================
  Files         986      986              
  Lines       49488    49520      +32     
  Branches     5843     5845       +2     
==========================================
+ Hits        20726    20731       +5     
- Misses      27852    27878      +26     
- Partials      910      911       +1     
Flag Coverage Δ
backend 39.92% <26.66%> (-0.02%) ⬇️
frontend 58.15% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...Areas/CTS/Models/CompetencyBundleAssociationDto.cs 90.38% <100.00%> (ø)
...b/Areas/Effort/Services/ClinicalScheduleService.cs 0.00% <ø> (ø)
web/Areas/Effort/Services/InstructorService.cs 47.63% <ø> (ø)
web/Areas/RAPS/Services/UinformService.cs 2.79% <ø> (ø)
web/Controllers/HomeController.cs 0.00% <ø> (ø)
...nicalScheduler/Controllers/CliniciansController.cs 36.97% <0.00%> (ø)
...Areas/Computing/Services/BiorenderStudentLookup.cs 0.00% <0.00%> (ø)
...eas/Effort/Controllers/ClinicalImportController.cs 0.00% <0.00%> (ø)
...as/Effort/Controllers/PercentRolloverController.cs 18.51% <0.00%> (ø)
...as/Effort/Services/Harvest/ClinicalHarvestPhase.cs 2.55% <0.00%> (ø)
... and 10 more

Comment thread test/Effort/HarvestTimeParserTests.cs Fixed
@rlorenzo
rlorenzo force-pushed the chore/sonar-1031-warnings branch from 92fb31b to 5be47a8 Compare August 8, 2026 06:33
@rlorenzo

rlorenzo commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The pull request updates nullable-flow handling across tests and web services, adds request-cancellation handling for streamed responses, clarifies background task cancellation, simplifies existence queries, and adds scoped analyzer suppressions.

Changes

Application cleanup

Layer / File(s) Summary
Request cancellation and safe output handling
web/Areas/CMS/Services/CmsFilePathSafety.cs, web/Classes/SitemapMiddleware.cs, web/ViteProxyHelpers.cs
Filename sanitization returns the default name after a regex timeout. Sitemap and proxy response operations observe RequestAborted and handle client disconnects.
Validated scheduler inputs and task startup
web/Areas/ClinicalScheduler/Controllers/InstructorScheduleController.cs, web/Areas/Effort/Controllers/ClinicalImportController.cs, web/Areas/Effort/Controllers/PercentRolloverController.cs
Controller methods use validated local values. Background tasks explicitly use CancellationToken.None while operation-level cancellation remains cooperative.
Query and transaction flow cleanup
web/Areas/CTS/Controllers/*, web/Areas/Students/Services/StudentList.cs, web/Areas/Effort/Services/ClinicalImportService.cs, web/Areas/Effort/Services/ClinicalScheduleService.cs
Existence checks use direct Any predicates. Import commit guards check transaction presence. The SQL analyzer warning is scoped around the existing parameterized query.
Nullable-flow and analyzer cleanup
web/Areas/CTS/Models/CompetencyBundleAssociationDto.cs, web/Areas/ClinicalScheduler/Controllers/CliniciansController.cs, web/Areas/Computing/Services/BiorenderStudentLookup.cs, web/Areas/Effort/Services/Harvest/*, web/Areas/Effort/Services/InstructorService.cs, web/Areas/RAPS/Services/*, web/Controllers/HomeController.cs
Redundant null-forgiving operators are removed. Scoped suppressions document the HMAC-SHA1, XML namespace, and anti-forgery cases.
Test assertion nullability cleanup
test/Areas/Directory/VMACSServiceTest.cs, test/CMS/*, test/ClinicalScheduler/PermissionsControllerTest.cs, test/Effort/HarvestTimeParserTests.cs, test/HealthChecks/HealthCheckCollectorTokenHandlerTests.cs, test/Scheduler/ScheduledJobRunnerTests.cs, test/Students/*
Tests use values established by prior assertions. The time parser test uses a typed Assert.IsType<TimeSpan> assertion.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant SitemapMiddleware
  participant ViteProxyHelpers
  participant ResponseStream
  Client->>SitemapMiddleware: disconnects request
  SitemapMiddleware->>ResponseStream: write with RequestAborted
  ResponseStream-->>SitemapMiddleware: cancellation
  SitemapMiddleware-->>Client: stop processing
  Client->>ViteProxyHelpers: disconnects proxy request
  ViteProxyHelpers->>ResponseStream: copy with RequestAborted
  ResponseStream-->>ViteProxyHelpers: cancellation
  ViteProxyHelpers-->>Client: suppress disconnect exception
Loading

Possibly related PRs

  • ucdavis/VIPER#191: Both changes address nullable-flow and analyzer cleanup, including overlapping HomeController.cs patterns.
  • ucdavis/VIPER#194: Both changes modify several overlapping controller and service areas, including InstructorScheduleController, SitemapMiddleware, and ViteProxyHelpers.
  • ucdavis/VIPER#227: Both changes update ViteProxyHelpers.cs request and response handling.

Suggested labels: .NET

Suggested reviewers: bniedzie, bsedwards

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.39% 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
Description check ✅ Passed The description clearly explains the warning remediation changes, behavioral changes, unresolved warning, and verification results.
Title check ✅ Passed The title clearly identifies the SonarAnalyzer warning cleanup as the primary purpose of the changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/sonar-1031-warnings

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.

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/ViteProxyHelpers.cs (1)

405-416: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Handle request-abort cancellation in the fallback path.

SendFileAsync and WriteAsync pass context.RequestAborted and can throw OperationCanceledException when the request is canceled. Add OperationCanceledException to the catch filter, or handle it when context.RequestAborted.IsCancellationRequested, then return without writing the 502 response.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/ViteProxyHelpers.cs` around lines 405 - 416, Update the static-file
fallback exception handling around SendFileAsync to recognize request-abort
OperationCanceledException when context.RequestAborted is canceled, log or
handle it as appropriate, and return before setting status 502 or calling
WriteAsync. Preserve the existing handling for file-related exceptions and
ensure canceled requests do not attempt a response write.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/Areas/CTS/Controllers/BundleCompetencyController.cs`:
- Around line 25-30: Update the read-only existence checks in
BundleCompetencyController.cs (lines 25-30) within BundleExists and
CompetencyExists, and BundleCompetencyGroupController.cs (lines 25-33) within
BundleExists and SameNameExists, by adding AsNoTracking() before each Any(...)
call.

In `@web/Areas/Students/Services/StudentList.cs`:
- Around line 61-63: Update the classYear filter in the surrounding student-list
method to replace the correlated _context.StudentClassYears.Any call with a
preloaded, AsNoTracking person-ID set for the requested classYear, then filter
eligible students using EF.Parameter(...).Contains(...) when the set has at
least 10 IDs; preserve the null-student exclusion and existing behavior for
smaller or empty sets.

---

Outside diff comments:
In `@web/ViteProxyHelpers.cs`:
- Around line 405-416: Update the static-file fallback exception handling around
SendFileAsync to recognize request-abort OperationCanceledException when
context.RequestAborted is canceled, log or handle it as appropriate, and return
before setting status 502 or calling WriteAsync. Preserve the existing handling
for file-related exceptions and ensure canceled requests do not attempt a
response write.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 325ff915-9b9f-42ec-9d0d-a885ddffc2a4

📥 Commits

Reviewing files that changed from the base of the PR and between 394ae2d and 5be47a8.

📒 Files selected for processing (31)
  • test/Areas/Directory/VMACSServiceTest.cs
  • test/CMS/CMSContentControllerTests.cs
  • test/CMS/CMSFilesControllerTests.cs
  • test/CMS/CMSLeftNavControllerTests.cs
  • test/CMS/CMSOptionsControllerTests.cs
  • test/ClinicalScheduler/PermissionsControllerTest.cs
  • test/Effort/HarvestTimeParserTests.cs
  • test/HealthChecks/HealthCheckCollectorTokenHandlerTests.cs
  • test/Scheduler/ScheduledJobRunnerTests.cs
  • test/Students/EmergencyContactControllerTests.cs
  • test/Students/EmergencyContactServiceTests.cs
  • web/Areas/CMS/Services/CmsFilePathSafety.cs
  • web/Areas/CTS/Controllers/BundleCompetencyController.cs
  • web/Areas/CTS/Controllers/BundleCompetencyGroupController.cs
  • web/Areas/CTS/Models/CompetencyBundleAssociationDto.cs
  • web/Areas/ClinicalScheduler/Controllers/CliniciansController.cs
  • web/Areas/ClinicalScheduler/Controllers/InstructorScheduleController.cs
  • web/Areas/Computing/Services/BiorenderStudentLookup.cs
  • web/Areas/Effort/Controllers/ClinicalImportController.cs
  • web/Areas/Effort/Controllers/PercentRolloverController.cs
  • web/Areas/Effort/Services/ClinicalImportService.cs
  • web/Areas/Effort/Services/ClinicalScheduleService.cs
  • web/Areas/Effort/Services/Harvest/ClinicalHarvestPhase.cs
  • web/Areas/Effort/Services/Harvest/CrestHarvestPhase.cs
  • web/Areas/Effort/Services/InstructorService.cs
  • web/Areas/RAPS/Services/OuGroupService.cs
  • web/Areas/RAPS/Services/UinformService.cs
  • web/Areas/Students/Services/StudentList.cs
  • web/Classes/SitemapMiddleware.cs
  • web/Controllers/HomeController.cs
  • web/ViteProxyHelpers.cs

Comment thread web/Areas/CTS/Controllers/BundleCompetencyController.cs Outdated
Comment thread web/Areas/Students/Services/StudentList.cs Outdated
41 sites flagged by S8969 across 20 files, 21 production and 20 test. Most
are a plain deletion; two spots needed the surrounding code to make the
non-null state provable instead:

- both clinical-import commits guard on ownsTransaction, which Sonar can
  follow but the compiler cannot; null-check the transaction itself, which
  is identical by construction
- AddInstructor and SetPrimaryEvaluator capture their [Required] nullable
  fields into non-null locals behind an explicit guard, which also clears
  the CodeQL nullable-dereference findings on those lines
@rlorenzo
rlorenzo force-pushed the chore/sonar-1031-warnings branch from 5be47a8 to 3c9f501 Compare August 8, 2026 08:26
@rlorenzo
rlorenzo requested a lite review from Copilot August 8, 2026 17:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Reduces warning noise introduced by the SonarAnalyzer 10.31 upgrade by applying targeted refactors and narrowly scoped suppressions, while keeping behavior stable (with a few intentional cancellation-handling tweaks at middleware/proxy boundaries).

Changes:

  • Pass context.RequestAborted through streaming/copy operations and swallow request-abort cancellations where a disconnect is not an error signal.
  • Remove redundant null-forgiving operators and simplify LINQ patterns (Where(...).Any()Any(...)), plus add .AsNoTracking() to existence checks.
  • Add narrowly scoped suppressions/justifications for security analyzers where the flagged pattern is intentional (parameterized SQL placeholder list, CAS XML namespace literal, anonymous error page CSRF suppression, legacy HMACSHA1 requirement) and harden CMS filename sanitization with a regex timeout.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated no comments.

Show a summary per file
File Description
web/ViteProxyHelpers.cs Propagate RequestAborted during proxy response streaming and avoid misclassifying client disconnects as Vite outages.
web/Controllers/HomeController.cs Add scoped suppressions with justifications for CAS XML namespace literal and anonymous error handler antiforgery.
web/Classes/SitemapMiddleware.cs Treat client disconnect during sitemap streaming as a normal cancellation and stop pipeline execution.
web/Areas/Students/Services/StudentList.cs Simplify .Where(...).Any() into .Any(...) within a composed EF query.
web/Areas/RAPS/Services/UinformService.cs Suppress Sonar weak-crypto rule alongside existing CA suppression for legacy HMACSHA1 requirement.
web/Areas/RAPS/Services/OuGroupService.cs Remove a redundant null-forgiving operator in group member login ID projection.
web/Areas/Effort/Services/InstructorService.cs Remove null-forgiving operators in AAUD ID → PKey dictionary creation and downstream usage.
web/Areas/Effort/Services/Harvest/CrestHarvestPhase.cs Remove null-forgiving operators in AAUD ID/PKey extraction and lookups.
web/Areas/Effort/Services/Harvest/ClinicalHarvestPhase.cs Remove redundant null-forgiving operator in importable MothraId filtering.
web/Areas/Effort/Services/ClinicalScheduleService.cs Add justification suppression for interpolated SQL that only injects parameter names.
web/Areas/Effort/Services/ClinicalImportService.cs Make transaction commit guard provable (transaction != null) and reduce null-forgiving usage in title-code filtering.
web/Areas/Effort/Controllers/PercentRolloverController.cs Use CancellationToken.None for Task.Run to ensure channel completion semantics for SSE.
web/Areas/Effort/Controllers/ClinicalImportController.cs Same SSE/channel completion fix as rollover stream.
web/Areas/CTS/Models/CompetencyBundleAssociationDto.cs Remove redundant null-forgiving operator in DTO projection.
web/Areas/CTS/Controllers/BundleCompetencyGroupController.cs Use .AsNoTracking() for existence/name checks and simplify .Where().Any() to .Any().
web/Areas/CTS/Controllers/BundleCompetencyController.cs Use .AsNoTracking() for existence checks and simplify .Where().Any() to .Any().
web/Areas/Computing/Services/BiorenderStudentLookup.cs Remove pointless null filtering after Task.WhenAll when tasks always yield constructed results.
web/Areas/CMS/Services/CmsFilePathSafety.cs Add regex timeout + fail-safe handling to prevent request-thread pinning on pathological filenames.
web/Areas/ClinicalScheduler/Controllers/InstructorScheduleController.cs Capture required nullable request fields into non-null locals after explicit guards to satisfy nullable analysis.
web/Areas/ClinicalScheduler/Controllers/CliniciansController.cs Remove redundant null-forgiving operator in rotation ordering projection.
test/Students/EmergencyContactServiceTests.cs Remove redundant null-forgiving in assertions.
test/Students/EmergencyContactControllerTests.cs Remove redundant null-forgiving in result/method assertions.
test/Scheduler/ScheduledJobRunnerTests.cs Remove redundant null-forgiving in assertion.
test/HealthChecks/HealthCheckCollectorTokenHandlerTests.cs Remove redundant null-forgiving in header assertion.
test/Effort/HarvestTimeParserTests.cs Simplify nullable assertion by asserting the concrete type.
test/CMS/CMSOptionsControllerTests.cs Remove redundant null-forgiving in assertions.
test/CMS/CMSLeftNavControllerTests.cs Remove redundant null-forgiving in assertions.
test/CMS/CMSFilesControllerTests.cs Remove redundant null-forgiving in assertions.
test/CMS/CMSContentControllerTests.cs Remove redundant null-forgiving in assertions.
test/ClinicalScheduler/PermissionsControllerTest.cs Remove redundant null-forgiving in dynamic response assertions.
test/Areas/Directory/VMACSServiceTest.cs Remove redundant null-forgiving in assertion.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 31 out of 31 changed files in this pull request and generated no new comments.

The Any in GetStudents was correlated to every outer StudentClassYears row.
Load the matching person ids once and match with EF.Parameter(...).Contains
so the filter becomes a single IN list.
@rlorenzo
rlorenzo force-pushed the chore/sonar-1031-warnings branch from 089a3dd to f086392 Compare August 8, 2026 17:37
@rlorenzo
rlorenzo requested a lite review from Copilot August 8, 2026 17:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 31 out of 31 changed files in this pull request and generated no new comments.

Suppressed comments (1)

web/Areas/Students/Services/StudentList.cs:69

  • This change materializes all PersonIds for the class year into memory via ToListAsync, which can be large and adds an extra round-trip. You can keep it as a single SQL query without a correlated subquery by using a queryable subquery/IN (SELECT ...) instead of pre-loading the IDs.
                    .ToListAsync();

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.

3 participants