-
Notifications
You must be signed in to change notification settings - Fork 330
PATCH release/component/project returns 400 Bad Request on duplicate name/version instead of 409 Conflict #4011
Description
Description
Ran into something weird with the PATCH release endpoint. When trying to update a release's version to one that already exists under the same component, the API returns 400 Bad Request instead of 409 Conflict. The backend is actually doing the right thing here; ComponentDatabaseHandler catches the duplicate and returns RequestStatus.DUPLICATE; but that status has no explicit handling in Sw360ReleaseService.updateRelease() so it falls through to the generic catch-all, becomes a plain RuntimeException, and RestExceptionHandler maps it to 400. Same issue on PATCH components and PATCH projects.
How to reproduce
Create two releases under the same component:
POST /api/releases
{"name": "OpenSSL", "version": "1.0.0", "componentId": "<cid>"}
POST /api/releases
{"name": "OpenSSL", "version": "2.0.0", "componentId": "<cid>"}
Then patch the second one to use the same version as the first:
PATCH /api/releases/<second-release-id>
Content-Type: application/json
{"version": "1.0.0"}
What comes back:
HTTP/1.1 400 Bad Request
{"status": 400, "error": "Bad Request", "message": "sw360 release with name 'OpenSSL 1.0.0 cannot be updated."}What should come back:
HTTP/1.1 409 Conflict
Looking at Sw360ReleaseService.updateRelease() around line 322, there's explicit handling for INVALID_INPUT, NAMINGERROR, DUPLICATE_ATTACHMENT etc. but DUPLICATE is just missing from that list. So it drops into the final else if (requestStatus != SUCCESS && requestStatus != SENT_TO_MODERATOR) block, throws a generic RuntimeException, and RestExceptionHandler.handleRuntimeException() turns that into a 400. The fix is straightforward — just needs an explicit branch for DUPLICATE that throws something mapping to 409. Sw360ComponentService and Sw360ProjectService have the exact same gap.
The annoying part is that ComponentDatabaseHandler is handling this correctly; the duplicate detection works, RequestStatus.DUPLICATE is returned as it should be; the information just gets lost on the way back up through the service layer.
Screenshots (if applicable)
N/A, the steps above reproduce it reliably.
Versions
- Reproduced on current main, last commit 014c574
SW360 logs
Nothing useful will show up in the logs for this; since the backend returned a status code cleanly rather than throwing, there's no stack trace or error logged anywhere. That's also part of what makes it tricky to diagnose if someone hits it without already knowing where to look.