Skip to content

Commit e2c34e0

Browse files
fix: improve shard publish error logging
1 parent d447c7f commit e2c34e0

2 files changed

Lines changed: 53 additions & 5 deletions

File tree

‎index/builder.go‎

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,11 @@ func (b *Builder) Finish() error {
669669

670670
b.flush()
671671
b.building.Wait()
672+
recordBuildError := func(err error) {
673+
if err != nil && b.buildError == nil {
674+
b.buildError = err
675+
}
676+
}
672677

673678
if b.buildError != nil {
674679
for tmp := range b.finishedShards {
@@ -766,7 +771,7 @@ func (b *Builder) Finish() error {
766771
for _, name := range oldShards {
767772
paths, err := IndexFilePaths(name)
768773
if err != nil {
769-
b.buildError = fmt.Errorf("failed to find old paths for %s: %w", name, err)
774+
recordBuildError(fmt.Errorf("failed to find old paths for %s: %w", name, err))
770775
}
771776
for _, p := range paths {
772777
toDelete[p] = struct{}{}
@@ -776,7 +781,16 @@ func (b *Builder) Finish() error {
776781

777782
for tmp, final := range artifactPaths {
778783
if err := os.Rename(tmp, final); err != nil {
779-
b.buildError = err
784+
log.Printf(
785+
"failed to publish shard: rename %q to %q: %T: %v; temporary path: %s; final path: %s",
786+
tmp,
787+
final,
788+
err,
789+
err,
790+
fileState(tmp),
791+
fileState(final),
792+
)
793+
recordBuildError(fmt.Errorf("publishing shard: rename %q to %q: %w", tmp, final, err))
780794
continue
781795
}
782796

@@ -791,19 +805,27 @@ func (b *Builder) Finish() error {
791805
if !strings.HasSuffix(p, ".zoekt") {
792806
continue
793807
}
794-
err := SetTombstone(p, b.opts.RepositoryDescription.ID)
795-
b.buildError = err
808+
recordBuildError(SetTombstone(p, b.opts.RepositoryDescription.ID))
796809
continue
797810
}
798811
log.Printf("removing old shard file: %s", p)
799812
if err := os.Remove(p); err != nil {
800-
b.buildError = err
813+
recordBuildError(fmt.Errorf("removing old shard file %q: %w", p, err))
801814
}
802815
}
803816

804817
return b.buildError
805818
}
806819

820+
func fileState(path string) string {
821+
info, err := os.Lstat(path)
822+
if err != nil {
823+
return fmt.Sprintf("stat error: %v", err)
824+
}
825+
826+
return fmt.Sprintf("mode=%s size=%d modtime=%s", info.Mode(), info.Size(), info.ModTime().Format(time.RFC3339Nano))
827+
}
828+
807829
// BranchNamesEqual compares the given zoekt.RepositoryBranch slices, and returns true
808830
// iff both slices specify the same set of branch names in the same order.
809831
func BranchNamesEqual(a, b []zoekt.RepositoryBranch) bool {

‎index/builder_test.go‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,32 @@ func TestBuildv16(t *testing.T) {
9797
}
9898
}
9999

100+
func TestBuilderFinishPreservesShardPublishError(t *testing.T) {
101+
indexDir := t.TempDir()
102+
opts := Options{
103+
IndexDir: indexDir,
104+
RepositoryDescription: zoekt.Repository{
105+
Name: "repo",
106+
},
107+
DisableCTags: true,
108+
}
109+
110+
b, err := NewBuilder(opts)
111+
require.NoError(t, err)
112+
require.NoError(t, b.AddFile("main.go", []byte("package main")))
113+
114+
// A non-empty directory at the final shard path makes both publishing the
115+
// new shard and cleaning up the apparent old shard fail. The publish error
116+
// is the useful root cause and must not be overwritten by the cleanup error.
117+
finalPath := b.opts.shardName(0)
118+
require.NoError(t, os.Mkdir(finalPath, 0o755))
119+
require.NoError(t, os.WriteFile(filepath.Join(finalPath, "keep"), nil, 0o644))
120+
121+
err = b.Finish()
122+
require.ErrorContains(t, err, "publishing shard")
123+
require.ErrorContains(t, err, finalPath)
124+
}
125+
100126
func TestFlags(t *testing.T) {
101127
cases := []struct {
102128
args []string

0 commit comments

Comments
 (0)