A community based topic aggregation platform built on atproto
11
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

+22 -22
+5 -5
internal/db/postgres/aggregator_repo.go
··· 145 145 if err != nil { 146 146 return nil, fmt.Errorf("failed to get aggregators: %w", err) 147 147 } 148 - defer rows.Close() 148 + defer func() { _ = rows.Close() }() 149 149 150 150 var results []*aggregators.Aggregator 151 151 for rows.Next() { ··· 279 279 if err != nil { 280 280 return nil, fmt.Errorf("failed to list aggregators: %w", err) 281 281 } 282 - defer rows.Close() 282 + defer func() { _ = rows.Close() }() 283 283 284 284 var aggs []*aggregators.Aggregator 285 285 for rows.Next() { ··· 632 632 if err != nil { 633 633 return nil, fmt.Errorf("failed to list authorizations for aggregator: %w", err) 634 634 } 635 - defer rows.Close() 635 + defer func() { _ = rows.Close() }() 636 636 637 637 return scanAuthorizations(rows) 638 638 } ··· 662 662 if err != nil { 663 663 return nil, fmt.Errorf("failed to list authorizations for community: %w", err) 664 664 } 665 - defer rows.Close() 665 + defer func() { _ = rows.Close() }() 666 666 667 667 return scanAuthorizations(rows) 668 668 } ··· 730 730 if err != nil { 731 731 return nil, fmt.Errorf("failed to get recent posts: %w", err) 732 732 } 733 - defer rows.Close() 733 + defer func() { _ = rows.Close() }() 734 734 735 735 var posts []*aggregators.AggregatorPost 736 736 for rows.Next() {
+3 -3
internal/db/postgres/vote_repo.go
··· 96 96 97 97 // GetByVoterAndSubject retrieves a user's vote on a specific subject 98 98 // Used by service to check existing vote state before creating/toggling 99 - func (r *postgresVoteRepo) GetByVoterAndSubject(ctx context.Context, voterDID string, subjectURI string) (*votes.Vote, error) { 99 + func (r *postgresVoteRepo) GetByVoterAndSubject(ctx context.Context, voterDID, subjectURI string) (*votes.Vote, error) { 100 100 query := ` 101 101 SELECT 102 102 id, uri, cid, rkey, voter_did, ··· 170 170 if err != nil { 171 171 return nil, fmt.Errorf("failed to list votes by subject: %w", err) 172 172 } 173 - defer rows.Close() 173 + defer func() { _ = rows.Close() }() 174 174 175 175 var result []*votes.Vote 176 176 for rows.Next() { ··· 211 211 if err != nil { 212 212 return nil, fmt.Errorf("failed to list votes by voter: %w", err) 213 213 } 214 - defer rows.Close() 214 + defer func() { _ = rows.Close() }() 215 215 216 216 var result []*votes.Vote 217 217 for rows.Next() {
+11 -11
internal/db/postgres/vote_repo_test.go
··· 52 52 53 53 func TestVoteRepo_Create(t *testing.T) { 54 54 db := setupTestDB(t) 55 - defer db.Close() 55 + defer func() { _ = db.Close() }() 56 56 defer cleanupVotes(t, db) 57 57 58 58 repo := NewVoteRepository(db) ··· 81 81 82 82 func TestVoteRepo_Create_Idempotent(t *testing.T) { 83 83 db := setupTestDB(t) 84 - defer db.Close() 84 + defer func() { _ = db.Close() }() 85 85 defer cleanupVotes(t, db) 86 86 87 87 repo := NewVoteRepository(db) ··· 123 123 124 124 func TestVoteRepo_Create_VoterNotFound(t *testing.T) { 125 125 db := setupTestDB(t) 126 - defer db.Close() 126 + defer func() { _ = db.Close() }() 127 127 defer cleanupVotes(t, db) 128 128 129 129 repo := NewVoteRepository(db) ··· 153 153 154 154 func TestVoteRepo_GetByURI(t *testing.T) { 155 155 db := setupTestDB(t) 156 - defer db.Close() 156 + defer func() { _ = db.Close() }() 157 157 defer cleanupVotes(t, db) 158 158 159 159 repo := NewVoteRepository(db) ··· 187 187 188 188 func TestVoteRepo_GetByURI_NotFound(t *testing.T) { 189 189 db := setupTestDB(t) 190 - defer db.Close() 190 + defer func() { _ = db.Close() }() 191 191 192 192 repo := NewVoteRepository(db) 193 193 ctx := context.Background() ··· 198 198 199 199 func TestVoteRepo_GetByVoterAndSubject(t *testing.T) { 200 200 db := setupTestDB(t) 201 - defer db.Close() 201 + defer func() { _ = db.Close() }() 202 202 defer cleanupVotes(t, db) 203 203 204 204 repo := NewVoteRepository(db) ··· 233 233 234 234 func TestVoteRepo_GetByVoterAndSubject_NotFound(t *testing.T) { 235 235 db := setupTestDB(t) 236 - defer db.Close() 236 + defer func() { _ = db.Close() }() 237 237 238 238 repo := NewVoteRepository(db) 239 239 ctx := context.Background() ··· 244 244 245 245 func TestVoteRepo_Delete(t *testing.T) { 246 246 db := setupTestDB(t) 247 - defer db.Close() 247 + defer func() { _ = db.Close() }() 248 248 defer cleanupVotes(t, db) 249 249 250 250 repo := NewVoteRepository(db) ··· 283 283 284 284 func TestVoteRepo_Delete_Idempotent(t *testing.T) { 285 285 db := setupTestDB(t) 286 - defer db.Close() 286 + defer func() { _ = db.Close() }() 287 287 defer cleanupVotes(t, db) 288 288 289 289 repo := NewVoteRepository(db) ··· 316 316 317 317 func TestVoteRepo_ListBySubject(t *testing.T) { 318 318 db := setupTestDB(t) 319 - defer db.Close() 319 + defer func() { _ = db.Close() }() 320 320 defer cleanupVotes(t, db) 321 321 322 322 repo := NewVoteRepository(db) ··· 362 362 363 363 func TestVoteRepo_ListByVoter(t *testing.T) { 364 364 db := setupTestDB(t) 365 - defer db.Close() 365 + defer func() { _ = db.Close() }() 366 366 defer cleanupVotes(t, db) 367 367 368 368 repo := NewVoteRepository(db)
+3 -3
tests/integration/aggregator_e2e_test.go
··· 50 50 t.Skipf("PDS not available at %s - run 'make dev-up' to start it", pdsURL) 51 51 } 52 52 if resp != nil { 53 - resp.Body.Close() 53 + _ = resp.Body.Close() 54 54 } 55 55 db := setupTestDB(t) 56 56 defer func() { ··· 513 513 // Views is []interface{}, unmarshal to check fields 514 514 viewJSON, _ := json.Marshal(response.Views[0]) 515 515 var view aggregator.AggregatorView 516 - json.Unmarshal(viewJSON, &view) 516 + _ = json.Unmarshal(viewJSON, &view) 517 517 518 518 assert.Equal(t, aggregatorDID, view.DID) 519 519 assert.Equal(t, "RSS Feed Aggregator", view.DisplayName) ··· 544 544 545 545 viewJSON, _ := json.Marshal(response.Views[0]) 546 546 var detailedView aggregator.AggregatorViewDetailed 547 - json.Unmarshal(viewJSON, &detailedView) 547 + _ = json.Unmarshal(viewJSON, &detailedView) 548 548 549 549 assert.Equal(t, aggregatorDID, detailedView.DID) 550 550 assert.Equal(t, 1, detailedView.Stats.CommunitiesUsing)