+11
.golangci.yml
+11
.golangci.yml
···
25
25
linters:
26
26
- errcheck
27
27
28
+
# TODO: fix issues and remove these paths one by one
29
+
- path: pkg/auth
30
+
linters:
31
+
- errcheck
32
+
- path: pkg/appview
33
+
linters:
34
+
- errcheck
35
+
- path: cmd/credential-helper
36
+
linters:
37
+
- errcheck
38
+
28
39
formatters:
29
40
enable:
30
41
- gofmt
+24
.tangled/workflows/lint.yaml
+24
.tangled/workflows/lint.yaml
···
1
+
when:
2
+
- event: ["push"]
3
+
branch: ["*"]
4
+
- event: ["pull_request"]
5
+
branch: ["main"]
6
+
7
+
engine: kubernetes
8
+
image: golang:1.25-trixie
9
+
architecture: amd64
10
+
11
+
steps:
12
+
- name: Download and Generate
13
+
environment:
14
+
CGO_ENABLED: 1
15
+
command: |
16
+
go mod download
17
+
go generate ./...
18
+
19
+
- name: Run Linter
20
+
environment:
21
+
CGO_ENABLED: 1
22
+
command: |
23
+
curl -sSfL https://golangci-lint.run/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.7.2
24
+
golangci-lint run ./...
+102
-26
pkg/hold/pds/xrpc.go
+102
-26
pkg/hold/pds/xrpc.go
···
207
207
}
208
208
209
209
w.Header().Set("Content-Type", "application/json")
210
-
json.NewEncoder(w).Encode(response)
210
+
if err := json.NewEncoder(w).Encode(response); err != nil {
211
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
212
+
w.WriteHeader(http.StatusInternalServerError)
213
+
}
211
214
}
212
215
213
216
// HandleDescribeServer returns server metadata
···
227
230
}
228
231
229
232
w.Header().Set("Content-Type", "application/json")
230
-
json.NewEncoder(w).Encode(response)
233
+
if err := json.NewEncoder(w).Encode(response); err != nil {
234
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
235
+
w.WriteHeader(http.StatusInternalServerError)
236
+
}
231
237
}
232
238
233
239
// HandleResolveHandle resolves a handle to a DID
···
255
261
}
256
262
257
263
w.Header().Set("Content-Type", "application/json")
258
-
json.NewEncoder(w).Encode(response)
264
+
if err := json.NewEncoder(w).Encode(response); err != nil {
265
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
266
+
w.WriteHeader(http.StatusInternalServerError)
267
+
}
259
268
}
260
269
261
270
// HandleGetProfile returns aggregated profile information
···
290
299
response := h.buildProfileResponse(r.Context())
291
300
292
301
w.Header().Set("Content-Type", "application/json")
293
-
json.NewEncoder(w).Encode(response)
302
+
if err := json.NewEncoder(w).Encode(response); err != nil {
303
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
304
+
w.WriteHeader(http.StatusInternalServerError)
305
+
}
294
306
}
295
307
296
308
// HandleGetProfiles returns aggregated profile information for multiple actors
···
341
353
}
342
354
343
355
w.Header().Set("Content-Type", "application/json")
344
-
json.NewEncoder(w).Encode(response)
356
+
if err := json.NewEncoder(w).Encode(response); err != nil {
357
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
358
+
w.WriteHeader(http.StatusInternalServerError)
359
+
}
345
360
}
346
361
347
362
// buildProfileResponse builds a profile response map (shared by GetProfile and GetProfiles)
···
435
450
}
436
451
437
452
w.Header().Set("Content-Type", "application/json")
438
-
json.NewEncoder(w).Encode(response)
453
+
if err := json.NewEncoder(w).Encode(response); err != nil {
454
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
455
+
w.WriteHeader(http.StatusInternalServerError)
456
+
}
439
457
}
440
458
441
459
// HandleGetRecord retrieves a record from the repository
···
479
497
}
480
498
481
499
w.Header().Set("Content-Type", "application/json")
482
-
json.NewEncoder(w).Encode(response)
500
+
if err := json.NewEncoder(w).Encode(response); err != nil {
501
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
502
+
w.WriteHeader(http.StatusInternalServerError)
503
+
}
483
504
}
484
505
485
506
// HandleListRecords lists records in a collection
···
551
572
// Empty repo, return empty list
552
573
response := map[string]any{"records": []any{}}
553
574
w.Header().Set("Content-Type", "application/json")
554
-
json.NewEncoder(w).Encode(response)
575
+
if err := json.NewEncoder(w).Encode(response); err != nil {
576
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
577
+
w.WriteHeader(http.StatusInternalServerError)
578
+
}
555
579
return
556
580
}
557
581
···
598
622
}
599
623
600
624
w.Header().Set("Content-Type", "application/json")
601
-
json.NewEncoder(w).Encode(response)
625
+
if err := json.NewEncoder(w).Encode(response); err != nil {
626
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
627
+
w.WriteHeader(http.StatusInternalServerError)
628
+
}
602
629
}
603
630
604
631
// handleListRecordsMST uses the legacy MST-based listing (fallback for tests)
···
620
647
// Empty repo, return empty list
621
648
response := map[string]any{"records": []any{}}
622
649
w.Header().Set("Content-Type", "application/json")
623
-
json.NewEncoder(w).Encode(response)
650
+
if err := json.NewEncoder(w).Encode(response); err != nil {
651
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
652
+
w.WriteHeader(http.StatusInternalServerError)
653
+
}
624
654
return
625
655
}
626
656
···
729
759
}
730
760
731
761
w.Header().Set("Content-Type", "application/json")
732
-
json.NewEncoder(w).Encode(response)
762
+
if err := json.NewEncoder(w).Encode(response); err != nil {
763
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
764
+
w.WriteHeader(http.StatusInternalServerError)
765
+
}
733
766
}
734
767
735
768
// HandleDeleteRecord deletes a record from the repository
···
799
832
if !currentCID.Equals(swapRecordCID) {
800
833
// Swap failed - record CID doesn't match
801
834
w.WriteHeader(http.StatusBadRequest)
802
-
json.NewEncoder(w).Encode(map[string]any{
835
+
response := map[string]any{
803
836
"error": "InvalidSwap",
804
837
"message": "record CID does not match swapRecord",
805
-
})
838
+
}
839
+
if err := json.NewEncoder(w).Encode(response); err != nil {
840
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
841
+
w.WriteHeader(http.StatusInternalServerError)
842
+
}
806
843
return
807
844
}
808
845
}
···
846
883
}
847
884
848
885
w.Header().Set("Content-Type", "application/json")
849
-
json.NewEncoder(w).Encode(response)
886
+
if err := json.NewEncoder(w).Encode(response); err != nil {
887
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
888
+
w.WriteHeader(http.StatusInternalServerError)
889
+
}
850
890
}
851
891
852
892
// HandleSyncGetRecord returns a single record as a CAR file for sync
···
900
940
}
901
941
902
942
// Write the CAR data to the response
903
-
w.Write(buf.Bytes())
943
+
if _, err := w.Write(buf.Bytes()); err != nil {
944
+
slog.Error("failed to write car to http response", "error", err, "path", r.URL.Path)
945
+
w.WriteHeader(http.StatusInternalServerError)
946
+
}
904
947
}
905
948
906
949
// HandleGetRepo returns the full repository as a CAR file
···
1063
1106
}
1064
1107
1065
1108
w.Header().Set("Content-Type", "application/json")
1066
-
json.NewEncoder(w).Encode(response)
1109
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1110
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1111
+
w.WriteHeader(http.StatusInternalServerError)
1112
+
}
1067
1113
}
1068
1114
1069
1115
// HandleGetBlob routes blob requests to appropriate handlers based on blob type
···
1139
1185
"url": presignedURL,
1140
1186
}
1141
1187
w.Header().Set("Content-Type", "application/json")
1142
-
json.NewEncoder(w).Encode(response)
1188
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1189
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1190
+
w.WriteHeader(http.StatusInternalServerError)
1191
+
}
1143
1192
}
1144
1193
1145
1194
// handleGetATProtoBlob handles standard ATProto blob requests
···
1193
1242
"repos": []any{},
1194
1243
}
1195
1244
w.Header().Set("Content-Type", "application/json")
1196
-
json.NewEncoder(w).Encode(response)
1245
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1246
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1247
+
w.WriteHeader(http.StatusInternalServerError)
1248
+
}
1197
1249
return
1198
1250
}
1199
1251
···
1205
1257
"repos": []any{},
1206
1258
}
1207
1259
w.Header().Set("Content-Type", "application/json")
1208
-
json.NewEncoder(w).Encode(response)
1260
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1261
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1262
+
w.WriteHeader(http.StatusInternalServerError)
1263
+
}
1209
1264
return
1210
1265
}
1211
1266
···
1223
1278
}
1224
1279
1225
1280
w.Header().Set("Content-Type", "application/json")
1226
-
json.NewEncoder(w).Encode(response)
1281
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1282
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1283
+
w.WriteHeader(http.StatusInternalServerError)
1284
+
}
1227
1285
}
1228
1286
1229
1287
// HandleGetRepoStatus returns the hosting status for a repository
···
1252
1310
"active": true,
1253
1311
}
1254
1312
w.Header().Set("Content-Type", "application/json")
1255
-
json.NewEncoder(w).Encode(response)
1313
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1314
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1315
+
w.WriteHeader(http.StatusInternalServerError)
1316
+
}
1256
1317
return
1257
1318
}
1258
1319
···
1264
1325
}
1265
1326
1266
1327
w.Header().Set("Content-Type", "application/json")
1267
-
json.NewEncoder(w).Encode(response)
1328
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1329
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1330
+
w.WriteHeader(http.StatusInternalServerError)
1331
+
}
1268
1332
}
1269
1333
1270
1334
// HandleDIDDocument returns the DID document
···
1276
1340
}
1277
1341
1278
1342
w.Header().Set("Content-Type", "application/json")
1279
-
json.NewEncoder(w).Encode(doc)
1343
+
if err := json.NewEncoder(w).Encode(doc); err != nil {
1344
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1345
+
w.WriteHeader(http.StatusInternalServerError)
1346
+
}
1280
1347
}
1281
1348
1282
1349
// HandleAtprotoDID returns the DID for handle resolution
···
1375
1442
}
1376
1443
w.Header().Set("Content-Type", "application/json")
1377
1444
w.WriteHeader(http.StatusOK)
1378
-
json.NewEncoder(w).Encode(response)
1445
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1446
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1447
+
w.WriteHeader(http.StatusInternalServerError)
1448
+
}
1379
1449
return
1380
1450
}
1381
1451
}
···
1408
1478
1409
1479
w.Header().Set("Content-Type", "application/json")
1410
1480
w.WriteHeader(http.StatusCreated)
1411
-
json.NewEncoder(w).Encode(response)
1481
+
if err := json.NewEncoder(w).Encode(response); err != nil {
1482
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1483
+
w.WriteHeader(http.StatusInternalServerError)
1484
+
}
1412
1485
}
1413
1486
1414
1487
// GetPresignedURL generates a presigned URL for GET, HEAD, or PUT operations
···
1546
1619
}
1547
1620
1548
1621
w.Header().Set("Content-Type", "application/json")
1549
-
json.NewEncoder(w).Encode(stats)
1622
+
if err := json.NewEncoder(w).Encode(stats); err != nil {
1623
+
slog.Error("failed to encode json to http response", "error", err, "path", r.URL.Path)
1624
+
w.WriteHeader(http.StatusInternalServerError)
1625
+
}
1550
1626
}