Skip to content

Commit 36cf2ad

Browse files
committed
fixed the review comments
Generated with [GitHub Copilot](https://github.com/features/copilot) Signed-off-by: Prabodh Chaudhari <[email protected]>
1 parent d04022a commit 36cf2ad

File tree

7 files changed

+52
-16
lines changed

7 files changed

+52
-16
lines changed

charts/lfx-v2-mailing-list-service/values.local.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ app:
1313
jwtAuthDisabledMockLocalPrincipal: "test-super-admin"
1414
# Enable debug logging for local development
1515
logLevel: debug
16-
16+
1717
# Use mock repository for local testing
1818
repositorySource: mock
19-
19+
2020
# Use mock GroupsIO integration for local testing
2121
groupsio:
2222
source: mock

cmd/mailing-list-api/service/grpsio_webhook_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ func TestWebhook_AllEventTypes(t *testing.T) {
330330
service.WithMailingListReader(mockRepo),
331331
service.WithMailingListWriter(mock.NewMockGrpsIOMailingListWriter(mockRepo)),
332332
service.WithMemberReader(mockRepo),
333-
service.WithMemberWriter(mock.NewMockGrpsIOWriter(mockRepo)),
333+
service.WithMemberWriter(mock.NewMockGrpsIOMemberWriter(mockRepo)),
334334
)
335335

336336
svc := NewMailingList(
@@ -428,7 +428,7 @@ func TestWebhook_MemberEventMissingMemberInfo(t *testing.T) {
428428
service.WithMailingListReader(mockRepo),
429429
service.WithMailingListWriter(mock.NewMockGrpsIOMailingListWriter(mockRepo)),
430430
service.WithMemberReader(mockRepo),
431-
service.WithMemberWriter(mock.NewMockGrpsIOWriter(mockRepo)),
431+
service.WithMemberWriter(mock.NewMockGrpsIOMemberWriter(mockRepo)),
432432
)
433433

434434
svc := NewMailingList(

cmd/mailing-list-api/service/mailing_list_service.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package service
66

77
import (
88
"context"
9+
stderrors "errors"
910
"fmt"
1011
"log/slog"
1112
"time"
@@ -671,11 +672,26 @@ func (s *mailingListService) GroupsioWebhook(ctx context.Context, p *mailinglist
671672
})
672673

673674
if err != nil {
674-
slog.ErrorContext(ctx, "webhook processing failed after retries", "error", err)
675-
// Note: Still return nil (204) to prevent Groups.io from retrying
675+
// Check if this is a validation error (malformed data)
676+
var validationErr errors.Validation
677+
if stderrors.As(err, &validationErr) {
678+
// Validation errors should not trigger retries - log and return success
679+
slog.ErrorContext(ctx, "webhook validation failed - returning success to prevent retries",
680+
"error", err,
681+
"action", p.Action)
682+
return nil // Return 204 to prevent GroupsIO from retrying
683+
}
684+
685+
// For other errors (transient failures), return error to trigger GroupsIO retry
686+
slog.ErrorContext(ctx, "webhook processing failed after retries",
687+
"error", err,
688+
"action", p.Action,
689+
"retries", constants.WebhookMaxRetries)
690+
return &mailinglistservice.InternalServerError{Message: "webhook processing failed"}
676691
}
677692

678-
return nil // Always return nil for 204 No Content
693+
// Success - return 204 No Content
694+
return nil
679695
}
680696

681697
// Helper functions

internal/service/grpsio_mailing_list_writer.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/linuxfoundation/lfx-v2-mailing-list-service/internal/infrastructure/groupsio"
1616
"github.com/linuxfoundation/lfx-v2-mailing-list-service/pkg/constants"
1717
"github.com/linuxfoundation/lfx-v2-mailing-list-service/pkg/errors"
18+
"github.com/linuxfoundation/lfx-v2-mailing-list-service/pkg/log"
1819
"github.com/linuxfoundation/lfx-v2-mailing-list-service/pkg/utils"
1920
)
2021

@@ -158,7 +159,7 @@ func (ml *grpsIOWriterOrchestrator) CreateGrpsIOMailingList(ctx context.Context,
158159
if existing, revision, checkErr := ml.ensureMailingListIdempotent(ctx, request); checkErr == nil && existing != nil {
159160
slog.InfoContext(ctx, "constraint conflict resolved - returning existing record (race condition)",
160161
"mailing_list_uid", existing.UID,
161-
"subgroup_id", request.SubgroupID)
162+
"subgroup_id", log.LogOptionalInt64(request.SubgroupID))
162163
return existing, revision, nil
163164
}
164165
}
@@ -236,7 +237,7 @@ func (ml *grpsIOWriterOrchestrator) CreateGrpsIOMailingList(ctx context.Context,
236237
"mailing_list_uid", createdMailingList.UID,
237238
"group_name", createdMailingList.GroupName,
238239
"source", createdMailingList.Source,
239-
"subgroup_id", createdMailingList.SubgroupID,
240+
"subgroup_id", log.LogOptionalInt64(createdMailingList.SubgroupID),
240241
"parent_uid", createdMailingList.ServiceUID,
241242
"public", createdMailingList.Public,
242243
"committee_based", createdMailingList.IsCommitteeBased())

internal/service/grpsio_webhook_processor.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func (p *grpsIOWebhookProcessor) ProcessEvent(ctx context.Context, event *model.
108108

109109
func (p *grpsIOWebhookProcessor) handleSubGroupCreated(ctx context.Context, event *model.GrpsIOWebhookEvent) error {
110110
if event.Group == nil {
111-
return fmt.Errorf("missing group information in created_subgroup event")
111+
return errors.NewValidation("missing group information in created_subgroup event")
112112
}
113113

114114
parentGroupID := uint64(event.Group.ParentGroupID)
@@ -233,7 +233,7 @@ func (p *grpsIOWebhookProcessor) handleSubGroupDeleted(ctx context.Context, even
233233

234234
func (p *grpsIOWebhookProcessor) handleMemberAdded(ctx context.Context, event *model.GrpsIOWebhookEvent) error {
235235
if event.MemberInfo == nil {
236-
return fmt.Errorf("missing member info in added_member event")
236+
return errors.NewValidation("missing member info in added_member event")
237237
}
238238

239239
memberID := int64(event.MemberInfo.ID)
@@ -308,7 +308,7 @@ func (p *grpsIOWebhookProcessor) handleMemberAdded(ctx context.Context, event *m
308308

309309
func (p *grpsIOWebhookProcessor) handleMemberRemoved(ctx context.Context, event *model.GrpsIOWebhookEvent) error {
310310
if event.MemberInfo == nil {
311-
return fmt.Errorf("missing member info in removed_member event")
311+
return errors.NewValidation("missing member info in removed_member event")
312312
}
313313

314314
memberID := uint64(event.MemberInfo.ID)
@@ -356,7 +356,7 @@ func (p *grpsIOWebhookProcessor) handleMemberRemoved(ctx context.Context, event
356356

357357
func (p *grpsIOWebhookProcessor) handleMemberBanned(ctx context.Context, event *model.GrpsIOWebhookEvent) error {
358358
if event.MemberInfo == nil {
359-
return fmt.Errorf("missing member info in ban_members event")
359+
return errors.NewValidation("missing member info in ban_members event")
360360
}
361361

362362
slog.InfoContext(ctx, "received ban_members event",

pkg/log/log.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,22 @@ func Priority(level string) slog.Attr {
117117
func PriorityCritical() slog.Attr {
118118
return Priority(priorityCritical)
119119
}
120+
121+
// LogOptionalInt64 creates an slog.Value for optional int64 pointers.
122+
// Returns nil value if pointer is nil, otherwise logs the dereferenced value.
123+
// This helper ensures consistent logging of nullable int64 fields like IDs or timestamps.
124+
//
125+
// Example usage:
126+
//
127+
// slog.InfoContext(ctx, "operation completed",
128+
// "subgroup_id", utils.LogOptionalInt64(record.SubgroupID))
129+
//
130+
// Logs:
131+
// - When SubgroupID is nil: "subgroup_id": null
132+
// - When SubgroupID is &123: "subgroup_id": 123
133+
func LogOptionalInt64(val *int64) slog.Value {
134+
if val == nil {
135+
return slog.AnyValue(nil)
136+
}
137+
return slog.Int64Value(*val)
138+
}

pkg/utils/retry_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@ func TestRetryWithExponentialBackoff_ExponentialDelay(t *testing.T) {
151151
assert.GreaterOrEqual(t, delay3, 40*time.Millisecond)
152152

153153
// Verify each delay is approximately double the previous
154-
// Allow for some timing variance (within 2x range)
155-
assert.LessOrEqual(t, delay1, 2*delay1)
154+
// Allow for some timing variance (within ~2x range)
156155
assert.GreaterOrEqual(t, delay2, delay1)
157-
assert.LessOrEqual(t, delay2, 4*delay1)
156+
assert.LessOrEqual(t, delay2, 2*delay1)
158157
assert.GreaterOrEqual(t, delay3, delay2)
158+
assert.LessOrEqual(t, delay3, 2*delay2)
159159
}
160160

161161
func TestRetryWithExponentialBackoff_MaxDelayRespected(t *testing.T) {

0 commit comments

Comments
 (0)