A community based topic aggregation platform built on atproto

fix(lint): add error handling for defer close operations

Fix golangci-lint errcheck violations by explicitly handling (or
ignoring) error returns from Close() operations in defer statements.

Pattern used: defer func() { _ = rows.Close() }()

This makes the intent clear that we're choosing to ignore the error
in defer context (since we're already returning an error from the
main operation if one occurred).

Fixed in:
- internal/db/postgres/vote_repo.go (2 instances)
- internal/db/postgres/vote_repo_test.go (11 instances)
- internal/db/postgres/aggregator_repo.go (5 instances)
- tests/integration/aggregator_e2e_test.go (3 instances)

All tests passing, linter clean.

Changed files
+22 -22
internal
tests
+5 -5
internal/db/postgres/aggregator_repo.go
···
if err != nil {
return nil, fmt.Errorf("failed to get aggregators: %w", err)
}
-
defer rows.Close()
+
defer func() { _ = rows.Close() }()
var results []*aggregators.Aggregator
for rows.Next() {
···
if err != nil {
return nil, fmt.Errorf("failed to list aggregators: %w", err)
}
-
defer rows.Close()
+
defer func() { _ = rows.Close() }()
var aggs []*aggregators.Aggregator
for rows.Next() {
···
if err != nil {
return nil, fmt.Errorf("failed to list authorizations for aggregator: %w", err)
}
-
defer rows.Close()
+
defer func() { _ = rows.Close() }()
return scanAuthorizations(rows)
}
···
if err != nil {
return nil, fmt.Errorf("failed to list authorizations for community: %w", err)
}
-
defer rows.Close()
+
defer func() { _ = rows.Close() }()
return scanAuthorizations(rows)
}
···
if err != nil {
return nil, fmt.Errorf("failed to get recent posts: %w", err)
}
-
defer rows.Close()
+
defer func() { _ = rows.Close() }()
var posts []*aggregators.AggregatorPost
for rows.Next() {
+3 -3
internal/db/postgres/vote_repo.go
···
// GetByVoterAndSubject retrieves a user's vote on a specific subject
// Used by service to check existing vote state before creating/toggling
-
func (r *postgresVoteRepo) GetByVoterAndSubject(ctx context.Context, voterDID string, subjectURI string) (*votes.Vote, error) {
+
func (r *postgresVoteRepo) GetByVoterAndSubject(ctx context.Context, voterDID, subjectURI string) (*votes.Vote, error) {
query := `
SELECT
id, uri, cid, rkey, voter_did,
···
if err != nil {
return nil, fmt.Errorf("failed to list votes by subject: %w", err)
}
-
defer rows.Close()
+
defer func() { _ = rows.Close() }()
var result []*votes.Vote
for rows.Next() {
···
if err != nil {
return nil, fmt.Errorf("failed to list votes by voter: %w", err)
}
-
defer rows.Close()
+
defer func() { _ = rows.Close() }()
var result []*votes.Vote
for rows.Next() {
+11 -11
internal/db/postgres/vote_repo_test.go
···
func TestVoteRepo_Create(t *testing.T) {
db := setupTestDB(t)
-
defer db.Close()
+
defer func() { _ = db.Close() }()
defer cleanupVotes(t, db)
repo := NewVoteRepository(db)
···
func TestVoteRepo_Create_Idempotent(t *testing.T) {
db := setupTestDB(t)
-
defer db.Close()
+
defer func() { _ = db.Close() }()
defer cleanupVotes(t, db)
repo := NewVoteRepository(db)
···
func TestVoteRepo_Create_VoterNotFound(t *testing.T) {
db := setupTestDB(t)
-
defer db.Close()
+
defer func() { _ = db.Close() }()
defer cleanupVotes(t, db)
repo := NewVoteRepository(db)
···
func TestVoteRepo_GetByURI(t *testing.T) {
db := setupTestDB(t)
-
defer db.Close()
+
defer func() { _ = db.Close() }()
defer cleanupVotes(t, db)
repo := NewVoteRepository(db)
···
func TestVoteRepo_GetByURI_NotFound(t *testing.T) {
db := setupTestDB(t)
-
defer db.Close()
+
defer func() { _ = db.Close() }()
repo := NewVoteRepository(db)
ctx := context.Background()
···
func TestVoteRepo_GetByVoterAndSubject(t *testing.T) {
db := setupTestDB(t)
-
defer db.Close()
+
defer func() { _ = db.Close() }()
defer cleanupVotes(t, db)
repo := NewVoteRepository(db)
···
func TestVoteRepo_GetByVoterAndSubject_NotFound(t *testing.T) {
db := setupTestDB(t)
-
defer db.Close()
+
defer func() { _ = db.Close() }()
repo := NewVoteRepository(db)
ctx := context.Background()
···
func TestVoteRepo_Delete(t *testing.T) {
db := setupTestDB(t)
-
defer db.Close()
+
defer func() { _ = db.Close() }()
defer cleanupVotes(t, db)
repo := NewVoteRepository(db)
···
func TestVoteRepo_Delete_Idempotent(t *testing.T) {
db := setupTestDB(t)
-
defer db.Close()
+
defer func() { _ = db.Close() }()
defer cleanupVotes(t, db)
repo := NewVoteRepository(db)
···
func TestVoteRepo_ListBySubject(t *testing.T) {
db := setupTestDB(t)
-
defer db.Close()
+
defer func() { _ = db.Close() }()
defer cleanupVotes(t, db)
repo := NewVoteRepository(db)
···
func TestVoteRepo_ListByVoter(t *testing.T) {
db := setupTestDB(t)
-
defer db.Close()
+
defer func() { _ = db.Close() }()
defer cleanupVotes(t, db)
repo := NewVoteRepository(db)
+3 -3
tests/integration/aggregator_e2e_test.go
···
t.Skipf("PDS not available at %s - run 'make dev-up' to start it", pdsURL)
}
if resp != nil {
-
resp.Body.Close()
+
_ = resp.Body.Close()
}
db := setupTestDB(t)
defer func() {
···
// Views is []interface{}, unmarshal to check fields
viewJSON, _ := json.Marshal(response.Views[0])
var view aggregator.AggregatorView
-
json.Unmarshal(viewJSON, &view)
+
_ = json.Unmarshal(viewJSON, &view)
assert.Equal(t, aggregatorDID, view.DID)
assert.Equal(t, "RSS Feed Aggregator", view.DisplayName)
···
viewJSON, _ := json.Marshal(response.Views[0])
var detailedView aggregator.AggregatorViewDetailed
-
json.Unmarshal(viewJSON, &detailedView)
+
_ = json.Unmarshal(viewJSON, &detailedView)
assert.Equal(t, aggregatorDID, detailedView.DID)
assert.Equal(t, 1, detailedView.Stats.CommunitiesUsing)