fix: distinguish 404 in GetAllFilesInPath, make uploads idempotent #33
Reference in New Issue
Block a user
Delete Branch "fix/8-10-error-handling-idempotent-upload"
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?
Summary
Fixes two issues:
Issue #8: Distinguish 404 from other errors in GetAllFilesInPath
APIErrortype withStatusCodefield to carry HTTP status codes from Gitea API responsesIsNotFoundhelper function for ergonomic 404 checksGetAllFilesInPathnow only falls back to single-file fetch when the error is a 404 (path is a file, not a directory)Issue #10: Make release asset uploads idempotent
Tests
TestGetAllFilesInPath_404FallsBackToFile— verifies 404 triggers file fallbackTestGetAllFilesInPath_500Propagates— verifies 500 is propagated (no fallback)TestGetAllFilesInPath_403Propagates— verifies 403 is propagated (no fallback)TestIsNotFound— table test for the helper functionCloses #8
Closes #10
Gpt Review
Summary
This change robustly addresses 404 handling and release asset idempotency, introducing clear error typing and strong test coverage. Implementation is idiomatic and aligns with Go and repo conventions.
Recommendation
APPROVE — The update meaningfully improves error distinction in Gitea API handling by adding an idiomatic APIError type with status code propagation, and leverages this to prevent fallback-to-file for non-404 errors in GetAllFilesInPath. The new IsNotFound helper provides a clear ergonomic API for checking 404s, and the workflow improvement ensures release asset uploads are idempotent. Unit test coverage is comprehensive and table-driven as per project guidelines. All changes are well-designed, readable, and conform to standard Go error handling and style. No issues found—merge is recommended.
Review by gpt
Security Review
Summary
Changes introduce structured HTTP error handling (APIError) and a precise 404 check for safe fallback logic, plus idempotent asset uploads in the release workflow. CI has passed and no exploitable security issues are evident in the diff.
Recommendation
APPROVE — The introduction of APIError and IsNotFound improves error semantics without expanding the attack surface, and the release workflow’s pre-delete step makes uploads idempotent without exposing secrets or enabling injection. Inputs to API calls continue to be safely escaped, timeouts are in place, and no sensitive data is logged beyond server responses as before. Consider hardening the release asset lookup to robustly handle unusual filenames and HTTP failures, but this is not security-critical. Overall, the changes are safe to merge.
Review by security
Sonnet Review
Summary
The changes cleanly introduce a structured APIError with an IsNotFound helper and correctly adjust GetAllFilesInPath to only fall back on 404s, improving error handling. The release workflow gains idempotent asset uploads. Tests comprehensively cover the new behavior, and CI passed.
Findings
.gitea/workflows/release.yml.gitea/workflows/release.ymlRecommendation
APPROVE — Overall the implementation is solid and adheres to idiomatic Go error handling patterns. The new APIError type and IsNotFound helper allow precise control flow in GetAllFilesInPath, and the fix to wrap the correct error on file fallback is correct. Tests validate the new behavior for 404/403/500 conditions and IsNotFound. The release workflow improvements make uploads idempotent; consider replacing the jq usage with Python’s urllib.parse.quote to avoid an extra dependency and optionally make DELETE failures non-fatal if desired. With CI passing and no major issues found, this is good to merge.
Review by sonnet
@@ -74,2 +74,4 @@filename=$(basename "$file")echo "Uploading ${filename}..."# Check if asset already exists and delete it[NIT] The inline Python filter compares asset names using a shell-expanded ${filename} inside single quotes. If a filename ever contained a single quote, this would break the command. While current artifact names are safe, consider more robust quoting or using a tool like jq.
@@ -258,3 +281,4 @@// 404 means the path might be a file — try fetching directlycontent, fileErr := c.GetFileContent(ctx, owner, repo, path)if fileErr != nil {return nil, fmt.Errorf("path %q is neither a file nor directory: %w", path, err)[MINOR] In GetAllFilesInPath, when GetFileContent fails, the returned error wraps the earlier ListContents error (err) instead of the actual fileErr. This loses the specific cause of the file fetch failure. Prefer wrapping fileErr for better diagnostics.
Security Review
Summary
Security-focused changes look sound: API errors now preserve status codes to prevent masking non-404 failures, and the release workflow’s asset upload is made idempotent without exposing secrets. CI passed.
Findings
.gitea/workflows/release.ymlgitea/client.goRecommendation
APPROVE — The changes correctly distinguish 404s using a typed APIError and prevent masking other HTTP failures, improving security posture around error handling. The idempotent release upload logic avoids duplicate asset errors without exposing the token in logs. To harden further, URL-encode the asset filename when constructing the upload URL in the release workflow, and consider truncating response bodies in APIError messages if there’s any risk of verbose or sensitive content being logged. Otherwise, the PR is safe to merge.
Review by security
@@ -75,1 +75,4 @@echo "Uploading ${filename}..."# Check if asset already exists and delete itEXISTING_ID=$(export ASSET_NAME="${filename}"; curl -sS \[MINOR] The asset name is interpolated directly into the URL query string without URL-encoding (…/assets?name=${filename}). While current filenames are controlled and simple, not URL-encoding can cause unexpected behavior or edge-case injection via special characters. Consider URL-encoding the filename when building the query parameter.
@@ -16,6 +17,24 @@ import ("time")// APIError represents an HTTP error response from the Gitea API.[NIT] APIError.Error includes the entire response body in error strings. If upstream returns verbose bodies, this could leak detailed server messages into logs. Not a direct vulnerability here, but consider truncating or sanitizing bodies in errors if upstream may include sensitive details.
Security Review
Summary
Changes introduce a typed API error with status codes and improve idempotency of release asset uploads. No security vulnerabilities are apparent; the updates generally improve error handling and robustness.
Recommendation
APPROVE — CI passed and the modifications are security-neutral or improving: APIError enables precise 404 handling without masking other errors, and the release workflow now safely URL-encodes asset names and deletes any existing asset before upload. No exploitable issues were identified. Consider continuing to limit sensitive information in error messages and ensure the release environment has required tools (jq, python3) installed, but these are non-security concerns.
Review by security