From 7d1cf640497cbcdfb932e619b13624112c7e3865 Mon Sep 17 00:00:00 2001 From: "Sahdev P. Zala" Date: Thu, 23 Apr 2020 15:53:05 -0400 Subject: [PATCH] wal: fix panic when decoder not set Handle the related panic and clarify doc. --- wal/wal.go | 8 +++++++- wal/wal_test.go | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/wal/wal.go b/wal/wal.go index 883b864011c..0ca9946ebe8 100644 --- a/wal/wal.go +++ b/wal/wal.go @@ -61,6 +61,7 @@ var ( ErrCRCMismatch = errors.New("wal: crc mismatch") ErrSnapshotMismatch = errors.New("wal: snapshot mismatch") ErrSnapshotNotFound = errors.New("wal: snapshot not found") + ErrDecoderNotFound = errors.New("wal: decoder not found") crcTable = crc32.MakeTable(crc32.Castagnoli) ) @@ -95,7 +96,8 @@ type WAL struct { } // Create creates a WAL ready for appending records. The given metadata is -// recorded at the head of each WAL file, and can be retrieved with ReadAll. +// recorded at the head of each WAL file, and can be retrieved with ReadAll +// after the file is Open. func Create(lg *zap.Logger, dirpath string, metadata []byte) (*WAL, error) { if Exist(dirpath) { return nil, os.ErrExist @@ -434,6 +436,10 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. defer w.mu.Unlock() rec := &walpb.Record{} + + if w.decoder == nil { + return nil, state, nil, ErrDecoderNotFound + } decoder := w.decoder var match bool diff --git a/wal/wal_test.go b/wal/wal_test.go index 8154971ac18..254ddfbc376 100644 --- a/wal/wal_test.go +++ b/wal/wal_test.go @@ -1059,3 +1059,24 @@ func TestValidSnapshotEntriesAfterPurgeWal(t *testing.T) { t.Fatal(err) } } + +// TestReadAllFail ensure ReadAll error if used without opening the WAL +func TestReadAllFail(t *testing.T) { + dir, err := ioutil.TempDir(os.TempDir(), "waltest") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + // create initial WAL + f, err := Create(zap.NewExample(), dir, []byte("metadata")) + if err != nil { + t.Fatal(err) + } + f.Close() + // try to read without opening the WAL + _, _, _, err = f.ReadAll() + if err == nil || err != ErrDecoderNotFound { + t.Fatalf("err = %v, want ErrDecoderNotFound", err) + } +}