feat(api): adopt 422 Unprocessable Entity for validation errors (#469)#479
feat(api): adopt 422 Unprocessable Entity for validation errors (#469)#479nanotaboada merged 1 commit intomasterfrom
Conversation
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
WalkthroughThis pull request adopts HTTP status code Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Assessment against linked issues
Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📋 Issue PlannerBuilt with CodeRabbit's Coding Plans for faster development and fewer bugs. View plan used: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
test/Dotnet.Samples.AspNetCore.WebApi.Tests/Integration/PlayerWebApplicationTests.cs (1)
200-204:⚠️ Potential issue | 🟡 MinorUpdate the stale validation-status comment.
This branch now returns 422 for validation failures, so the comment still saying “400 validation error” is misleading.
📝 Proposed comment fix
- // BeUniqueSquadNumber, which returns a 400 validation error before the + // BeUniqueSquadNumber, which returns a 422 validation error before the🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/Dotnet.Samples.AspNetCore.WebApi.Tests/Integration/PlayerWebApplicationTests.cs` around lines 200 - 204, Update the stale comment in PlayerWebApplicationTests.cs to reflect that validation failures now return 422 instead of 400: change the sentence that currently reads “400 validation error” to “422 validation error (Unprocessable Entity)”; keep references to the controller's 409 Conflict branch, the "Create" validation rule set, and BeUniqueSquadNumber, and note that the 409 path is still covered by the unit test Post_Players_Existing_Returns409Conflict where validation is mocked.
🧹 Nitpick comments (1)
test/Dotnet.Samples.AspNetCore.WebApi.Tests/Unit/PlayerControllerTests.cs (1)
66-67: Add payload assertions to validation error tests.Both validation tests (lines 66-67 and 342-343) currently assert only the result type and status code. Per the division of responsibilities across test layers, unit tests should fully assert the
HttpValidationProblemDetailspayload including theStatusandErrorsdictionary. Add assertions for the validation error details.🧪 Proposed assertion coverage
var httpResult = result.Should().BeOfType<ProblemHttpResult>().Subject; httpResult.StatusCode.Should().Be(StatusCodes.Status422UnprocessableEntity); + var problemDetails = httpResult + .ProblemDetails.Should() + .BeOfType<HttpValidationProblemDetails>() + .Subject; + problemDetails.Status.Should().Be(StatusCodes.Status422UnprocessableEntity); + problemDetails + .Errors.Should() + .ContainKey("SquadNumber") + .WhoseValue.Should() + .Contain("SquadNumber must be greater than 0.");Apply the same assertions to both
Post_Players_ValidationError_Returns422UnprocessableEntity()(lines 66-67) andPut_PlayerBySquadNumber_ValidationError_Returns422UnprocessableEntity()(lines 342-343).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/Dotnet.Samples.AspNetCore.WebApi.Tests/Unit/PlayerControllerTests.cs` around lines 66 - 67, The tests Post_Players_ValidationError_Returns422UnprocessableEntity and Put_PlayerBySquadNumber_ValidationError_Returns422UnprocessableEntity only assert the response type and status code; add assertions to verify the ProblemHttpResult.Value is an HttpValidationProblemDetails and its Status equals StatusCodes.Status422UnprocessableEntity and that the Errors dictionary contains the expected validation entries. In each test, after obtaining var httpResult = result.Should().BeOfType<ProblemHttpResult>().Subject, cast/inspect httpResult.Value as HttpValidationProblemDetails and assert its Status property equals 422 and that the Errors collection contains the expected key(s) and message(s) for the validated fields (e.g., model property names used in the test), ensuring the payload is fully validated alongside the result type and status.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@CHANGELOG.md`:
- Line 49: Update the CHANGELOG line that currently reads "Field validation
failures now return `422 Unprocessable Entity` (RFC 4918) instead of `400 Bad
Request`; `400 Bad Request` is now reserved for malformed requests (unparseable
JSON, wrong `Content-Type`, route/body mismatch) per RFC 9457" to separate the
status-code guidance from Problem Details attribution: state that validation
failures return `422 Unprocessable Entity` (RFC 4918) and `400 Bad Request` is
reserved for malformed requests (unparseable JSON, wrong `Content-Type`,
route/body mismatch), and add a separate sentence that Problem Details
formatting follows RFC 9457; replace the original single sentence with these two
clearer sentences in CHANGELOG.md.
---
Outside diff comments:
In
`@test/Dotnet.Samples.AspNetCore.WebApi.Tests/Integration/PlayerWebApplicationTests.cs`:
- Around line 200-204: Update the stale comment in PlayerWebApplicationTests.cs
to reflect that validation failures now return 422 instead of 400: change the
sentence that currently reads “400 validation error” to “422 validation error
(Unprocessable Entity)”; keep references to the controller's 409 Conflict
branch, the "Create" validation rule set, and BeUniqueSquadNumber, and note that
the 409 path is still covered by the unit test
Post_Players_Existing_Returns409Conflict where validation is mocked.
---
Nitpick comments:
In `@test/Dotnet.Samples.AspNetCore.WebApi.Tests/Unit/PlayerControllerTests.cs`:
- Around line 66-67: The tests
Post_Players_ValidationError_Returns422UnprocessableEntity and
Put_PlayerBySquadNumber_ValidationError_Returns422UnprocessableEntity only
assert the response type and status code; add assertions to verify the
ProblemHttpResult.Value is an HttpValidationProblemDetails and its Status equals
StatusCodes.Status422UnprocessableEntity and that the Errors dictionary contains
the expected validation entries. In each test, after obtaining var httpResult =
result.Should().BeOfType<ProblemHttpResult>().Subject, cast/inspect
httpResult.Value as HttpValidationProblemDetails and assert its Status property
equals 422 and that the Errors collection contains the expected key(s) and
message(s) for the validated fields (e.g., model property names used in the
test), ensuring the payload is fully validated alongside the result type and
status.
🪄 Autofix (Beta)
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: CHILL
Plan: Pro
Run ID: e31967c3-f8c1-4ad4-9324-86e345803b5e
📒 Files selected for processing (5)
CHANGELOG.mdsrc/Dotnet.Samples.AspNetCore.WebApi/Controllers/PlayerController.cssrc/Dotnet.Samples.AspNetCore.WebApi/Middlewares/ExceptionMiddleware.cstest/Dotnet.Samples.AspNetCore.WebApi.Tests/Integration/PlayerWebApplicationTests.cstest/Dotnet.Samples.AspNetCore.WebApi.Tests/Unit/PlayerControllerTests.cs



Summary
422 Unprocessable Entityinstead of400 Bad Request, correctly distinguishing syntactically valid but semantically invalid requests from malformed ones400 Bad Requestis now reserved for genuinely malformed requests (unparseable JSON, wrongContent-Type, route/body squad number mismatch inPUT)ExceptionMiddlewareupdated to return 422 for uncaughtValidationExceptionas a safety netTest plan
Post_Players_ValidationError_Returns422UnprocessableEntity— unit + integrationPut_PlayerBySquadNumber_ValidationError_Returns422UnprocessableEntity— unit + integrationPut_PlayerBySquadNumber_SquadNumberMismatch_Returns400BadRequest— unchanged, still 400Closes #469
🤖 Generated with Claude Code
Summary by CodeRabbit