fix: library improvements - bug fixes, tests, and coverage badge#19
fix: library improvements - bug fixes, tests, and coverage badge#19tirthpatell merged 7 commits intomainfrom
Conversation
Greptile SummaryThis PR delivers a set of targeted concurrency and correctness fixes across the rate-limiter, HTTP client, and auth utilities, accompanied by a comprehensive new test suite and a CI coverage badge. Key changes:
Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[HTTPClient.Do] -->|ShouldWait?| B{rateLimiter.ShouldWait\nRLock: rateLimited && before resetTime}
B -->|yes| C[rateLimiter.Wait\nacquire Lock]
B -->|no| D[executeRequest loop]
C --> E{resetTime passed?}
E -->|yes| F[clear rateLimited\nreturn nil]
E -->|no| G{rateLimited?}
G -->|no| H[update lastRequestTime\nreturn nil]
G -->|yes| I[capture originalResetTime\nUnlock\ntime.After waitTime]
I --> J{ctx.Done or timer fires}
J -->|ctx.Done| K[return ctx.Err]
J -->|timer| L[re-acquire Lock\ncheck resetTime]
L --> M{resetTime after\noriginalResetTime?}
M -->|yes – rate limit extended| N[update originalResetTime\nrecalculate waitTime\nUnlock → loop]
N --> I
M -->|no – reset elapsed| O[rateLimited = false\nlastRequestTime = now\nUnlock return nil]
O --> D
D --> P{executeRequest}
P -->|status < 400| Q[return resp nil]
P -->|status >= 400| R[createErrorFromResponse\ncalls MarkRateLimited if 429]
R --> S{isRetryableError?}
S -->|yes – 429 or 5xx| T{retries left?}
T -->|yes| D
T -->|no| U[return nil wrappedErr]
S -->|no – 4xx auth/validation| V[return nil err]
Q --> W[Client checks statusCode != 200\ncalls handleAPIError for 2xx-3xx]
|
…nfig in NewHTTPClient - Add RLock/RUnlock to getUserID() to prevent data race on tokenInfo - Deduplicate handleAPIError() by delegating to httpClient.createErrorFromResponse() - NewHTTPClient now reads config.BaseURL and config.UserAgent instead of hardcoding defaults - RateLimiter.Reset() now clears the rateLimited flag
Add 73 unit tests covering auth, HTTP client, rate limiting, pagination, posts (create/read/delete), users, replies, insights, search, and locations. Introduce shared test helpers (testClient, jsonHandler, newTestHTTPClient, noopLogger) in test_helpers_test.go to reduce boilerplate.
Restore structured error_data.details parsing in handleAPIError instead of delegating to createErrorFromResponse, which lost the extracted details field. Add missing parameter assertions in AutoPublish and KeywordSearch tests, and add error type checks in negative test cases.
Wait() held the mutex for the entire sleep duration, blocking all concurrent callers of ShouldWait/UpdateFromHeaders/MarkRateLimited. Release the lock before the select/sleep and re-acquire briefly after. Downgrade ShouldWait() to RLock since the time check already guards the stale flag. Add test coverage badge to README via gist-backed shields.io endpoint, updated by CI on main pushes.
- Capture resetTime before releasing lock in Wait() so a concurrent MarkRateLimited() with a later reset time isn't clobbered on wakeup - Add -race flag to CI test step to validate concurrency fixes
When a newer MarkRateLimited() arrives while Wait() is sleeping, recurse into Wait() to honor the new deadline rather than returning nil. Avoids updating lastRequestTime when no request actually proceeds.
944f3f9 to
6a8b579
Compare
Avoid unbounded stack growth during rate-limit storms by using a for loop instead of recursion when the deadline is extended.
Summary
getUserID()-- addedRLockfor concurrent-safe token readshandleAPIError-- reverted premature dedup tocreateErrorFromResponsethat losterror_data.detailsparsingBaseURL/UserAgentconfig inNewHTTPClient-- previously hardcoded, now reads from config with fallbacksrateLimitedflag inRateLimiter.Reset()-- was missing, causing stale rate-limit stateRateLimiter.Wait()-- released lock beforeselect/sleep to unblock concurrent callersShouldWait()toRLock-- time check already guards stale flag, no write neededhttptest-based mockingauto_publish_text,search_type) and error type verificationTest plan
go test ./... -short -racepassesgo vet ./...clean