_make_request decodes 204 as an error: every result is not None delete reports failure on success (systemic, 6 modules) #20
Labels
No labels
api
architecture
auth
authentication
blocked
bug
chore
ci/cd
codec-constraints
component:blitz
component:chatter
component:entertainment
component:foodchain
component:forgejo-client
component:gatekeeper
component:mappy
component:monads
component:spiffy
deduplication
dependencies
documentation
enhancement
feature
fix
graphics
in-progress
lang:go
lang:python
lang:rust
lang:shell
lang:toml
lang:typescript
performance
pkg:agent
pkg:ai
pkg:coding-agent
pkg:tui
priority:critical
priority:high
priority:low
priority:medium
ready
resolution
review
security
technical-debt
testing
tracking
vendor
video-encoding
workgroup
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
kade/forgejo-client#20
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Severity: high (systemic false negative)
Every DELETE answers
204 No Content._make_requestcalledresponse.json()unconditionally, which raises on an empty body; the resultingexception was caught by the blanket
except Exceptionhandler, which printedError making request: Expecting value: line 1 column 1 (char 0)and returnedNone.Every module that reports success with the idiom
return result is not Nonetherefore returned
Falseon a delete that succeeded. Live proof: deleting athrowaway label printed that JSON error while the label was in fact gone and the
request returned 204.
Affected call sites (
is not Noneon a possibly-204 result):modules/issues.py:294(close_issue),modules/issues.py:534modules/branches.py:46modules/projects.py:75(delete_card; see also the swapped-args note there)modules/labels.py(delete_label)Fix (implemented in the working tree)
Treat an empty body as a successful, empty result:
{}is notNonesois not Nonenow means success, and{}stays falsy soif result else []list callers are unaffected. Genuine failures (4xx/5xx viaraise_for_status) still returnNone.Tests (tests/test_labels.py, new)
test_delete_204_reports_success-- asserts the 204 yields non-None and that.json()was never called on the empty body.test_delete_204_is_truthy_neutral_for_list_callers--{} == {}and stays falsy.test_failure_still_returns_none-- a 404 still returnsNone(guard againstover-correcting the fix into "always succeed").