code: func ReadRepairWAL(
  	ctx context.Context,
  	walDir string,
  	walsnap walpb.Snapshot,
  	factory WALFactory,
  ) (WAL, WALData, error) {
  	var (
  		reader   WAL
  		metadata []byte
  		st       raftpb.HardState
  		ents     []raftpb.Entry
  		err      error
  	)
  	repaired := false
  	for {
  		if reader, err = factory.Open(walDir, walsnap); err != nil {
  			return nil, WALData{}, errors.Wrap(err, "failed to open WAL")
  		}
  		if metadata, st, ents, err = reader.ReadAll(); err != nil {
  			if closeErr := reader.Close(); closeErr != nil {
  				return nil, WALData{}, closeErr
  			}
  			if _, ok := err.(encryption.ErrCannotDecrypt); ok {
  				return nil, WALData{}, errors.Wrap(err, "failed to decrypt WAL")
  			}
  			// we can only repair ErrUnexpectedEOF and we never repair twice.
  			if repaired || err != io.ErrUnexpectedEOF {
  				return nil, WALData{}, errors.Wrap(err, "irreparable WAL error")
  			}
  			if !wal.Repair(walDir) {
  				return nil, WALData{}, errors.Wrap(err, "WAL error cannot be repaired")
  			}
  			log.G(ctx).WithError(err).Info("repaired WAL error")
  			repaired = true
  			continue
  		}
  		break
  	}
  	return reader, WALData{
  		Metadata:  metadata,
  		HardState: st,
  		Entries:   ents,
  	}, nil
  }
docs: // ReadRepairWAL opens a WAL for reading, and attempts to read it.  If we can't read it, attempts to repair
  // and read again.