fix(api): raise domain exceptions where the caller needs the message - #50
Open
ExtraToast wants to merge 2 commits into
Open
fix(api): raise domain exceptions where the caller needs the message#50ExtraToast wants to merge 2 commits into
ExtraToast wants to merge 2 commits into
Conversation
`error(…)` throws IllegalStateException, whose message the shared advice now withholds (JorisJonkers-dev/kotlin-spring-commons#34). Most uses here are internal invariants and should stay withheld — "No handler registered for X", "not visible immediately after create", "empty response from gateway". These are not. Two conflicts the caller caused and needs to read become DomainExceptions with codes, so the message survives as a 400: - CreateProjectCommandHandler SLUG_ALREADY_IN_USE - CreateRepositoryCommandHandler REPOSITORY_ALREADY_REGISTERED Six lookups of an entity the caller named become NotFoundException, which is both the right status and a detail worth reading — they were 409s: - LinkRepositoryToProjectCommandHandler project, repository - AddGithubLinkCommandHandler project - OpenPullRequestCommandHandler workspace - AgentSessionController session (x2), workspace Deliberately unchanged: SendUserInputCommandHandler's generation conflict and AgentSessionController.restartConflict, which the UI reads as a 409 to drive its reattach flow. That contract is status-only, so the generic detail does not affect it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The added NotFoundException took stageInput to three throws, one over detekt's ThrowsCount limit. The session lookup and ownership check it inlined were already requireSessionInWorkspace verbatim, so calling that removes the duplication and the violation together. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Follow-up to JorisJonkers-dev/kotlin-spring-commons#34, which stops the shared advice returning
IllegalStateException's message.error(…)throws exactly that, so everyerror(…)in this service now produces a generic 409.For most of them that is correct — "No handler registered for X", "not visible immediately after create", "empty response from gateway", "workspace missing for session " are internal invariants and should stay withheld. Eight are not, and move onto the exception types this repo already uses elsewhere.
Conflicts the caller caused and needs to read →
DomainExceptionwith a code, so the message survives as a 400:CreateProjectCommandHandlerSLUG_ALREADY_IN_USECreateRepositoryCommandHandlerREPOSITORY_ALREADY_REGISTEREDLookups of an entity the caller named →
NotFoundException, which is both the right status and a detail worth reading. These were 409s:LinkRepositoryToProjectCommandHandler— project, repositoryAddGithubLinkCommandHandler— projectOpenPullRequestCommandHandler— workspaceAgentSessionController— session (×2), workspaceDeliberately unchanged
SendUserInputCommandHandler's generation conflict andAgentSessionController.restartConflict.agents-uireads a 409 from the restart path to drive its reattach flow (workspaces.ts,err.status === 409). That contract is status-only — it never reads the detail text — so the generic detail does not affect it, and neither status changes here.Status changes
Six paths move 409 → 404. Nothing in
api/src/test,api/src/integrationTestor the UIs asserts a 409 on any of them; the only 409 assertions are on the restart-conflict path above, which is an explicitResponseEntity, not an exception.Tests
Updated the five handler tests that asserted
IllegalStateExceptionto assert the new type and that the message still carries the slug / URL / id — the point of the change is that these messages survive, so the tests check the message, not just the type. Added anAgentSessionControllertest asserting the unknown-session path is a 404 whose detail still names what was missing.Verification
Not built locally —
./gradlewhere resolvesdev.jorisjonkers:kotlin-commons-*:0.7.1from GitHub Packages and this workstation shell has nogpr.user/gpr.token, so compilation fails at dependency resolution before reaching any source. Relying on CI for compile, test, ktlint and detekt; happy to re-run locally if someone points me at credentials.