Skip to content

Commit 57cc09f

Browse files
authored
Improved handler to recover from panic issue with malformed snapshots (#77)
1 parent e7e8051 commit 57cc09f

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

src/core/handler.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,17 @@ func (c *CoreHandler) syncUp(account model.Account, repositoryData *model.Reposi
164164
c.updateDomainStatus(account, model.StatusSynced, model.MessageSynced, utils.LogLevelInfo)
165165
}
166166

167-
func (c *CoreHandler) checkForChanges(account model.Account, content string) (model.DiffResult, model.Snapshot, error) {
167+
func (c *CoreHandler) checkForChanges(account model.Account, content string) (diff model.DiffResult, snapshot model.Snapshot, err error) {
168+
// Recover from any panic in comparatorService operations
169+
// Manual changes to respository data may contain inconsistencies that can cause panic
170+
defer func() {
171+
if r := recover(); r != nil {
172+
diff = model.DiffResult{}
173+
snapshot = model.Snapshot{}
174+
err = fmt.Errorf("%v", r)
175+
}
176+
}()
177+
168178
// Get Snapshot from API
169179
snapshotJsonFromApi, err := c.apiService.FetchSnapshot(account.Domain.ID, account.Environment)
170180

src/core/handler_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,35 @@ func TestAccountHandlerNotSync(t *testing.T) {
500500
tearDown()
501501
})
502502

503+
t.Run("Should not sync when comparatorService panics", func(t *testing.T) {
504+
// Given
505+
fakeGitService := NewFakeGitService()
506+
fakeApiService := NewFakeApiService()
507+
fakeComparatorService := NewFakeComparatorService()
508+
fakeComparatorService.throwPanicCheckDiff = true
509+
510+
coreHandler = NewCoreHandler(coreHandler.accountRepository, fakeApiService, fakeComparatorService)
511+
account := givenAccount()
512+
account.Domain.ID = "123-comparator-panic"
513+
accountCreated, _ := coreHandler.accountRepository.Create(&account)
514+
515+
// Test
516+
go coreHandler.StartAccountHandler(accountCreated.ID.Hex(), fakeGitService)
517+
518+
// Wait for goroutine to process
519+
time.Sleep(1 * time.Second)
520+
521+
// Assert
522+
accountFromDb, _ := coreHandler.accountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
523+
assert.Equal(t, model.StatusError, accountFromDb.Domain.Status)
524+
assert.Contains(t, accountFromDb.Domain.Message, "Panic occurred in CheckSnapshotDiff")
525+
assert.Equal(t, "123", accountFromDb.Domain.LastCommit)
526+
assert.NotEqual(t, "", accountFromDb.Domain.LastDate)
527+
assert.Equal(t, 0, accountFromDb.Domain.Version)
528+
529+
tearDown()
530+
})
531+
503532
t.Run("Should not sync when git token has no permission to push changes", func(t *testing.T) {
504533
// Given
505534
fakeGitService := NewFakeGitService()
@@ -738,3 +767,32 @@ func (f *FakeApiService) NewDataFromJson(jsonData []byte) model.Data {
738767
json.Unmarshal(jsonData, &data)
739768
return data
740769
}
770+
771+
type FakeComparatorService struct {
772+
throwPanicCheckDiff bool
773+
}
774+
775+
func NewFakeComparatorService() *FakeComparatorService {
776+
return &FakeComparatorService{}
777+
}
778+
779+
func (f *FakeComparatorService) CheckSnapshotDiff(left model.Snapshot, right model.Snapshot, diffType DiffType) model.DiffResult {
780+
if f.throwPanicCheckDiff {
781+
panic("Panic occurred in CheckSnapshotDiff")
782+
}
783+
return model.DiffResult{}
784+
}
785+
786+
func (f *FakeComparatorService) MergeResults(diffResults []model.DiffResult) model.DiffResult {
787+
return model.DiffResult{}
788+
}
789+
790+
func (f *FakeComparatorService) NewSnapshotFromJson(jsonData []byte) model.Snapshot {
791+
var snapshot model.Snapshot
792+
json.Unmarshal(jsonData, &snapshot)
793+
return snapshot
794+
}
795+
796+
func (f *FakeComparatorService) RemoveDeleted(diffResult model.DiffResult) model.DiffResult {
797+
return diffResult
798+
}

0 commit comments

Comments
 (0)