Make sure WAL Repair can handle wrapped errors

Signed-off-by: Goutham Veeramachaneni <gouthamve@gmail.com>
This commit is contained in:
Goutham Veeramachaneni 2018-09-19 11:40:07 +05:30
parent d1a6edae6f
commit c7d0d10da4
No known key found for this signature in database
GPG Key ID: F1C217E8E9023CAD
2 changed files with 6 additions and 3 deletions

View File

@ -255,15 +255,17 @@ Loop:
// Repair attempts to repair the WAL based on the error. // Repair attempts to repair the WAL based on the error.
// It discards all data after the corruption. // It discards all data after the corruption.
func (w *WAL) Repair(err error) error { func (w *WAL) Repair(origErr error) error {
// We could probably have a mode that only discards torn records right around // We could probably have a mode that only discards torn records right around
// the corruption to preserve as data much as possible. // the corruption to preserve as data much as possible.
// But that's not generally applicable if the records have any kind of causality. // But that's not generally applicable if the records have any kind of causality.
// Maybe as an extra mode in the future if mid-WAL corruptions become // Maybe as an extra mode in the future if mid-WAL corruptions become
// a frequent concern. // a frequent concern.
err := errors.Cause(origErr) // So that we can pick up errors even if wrapped.
cerr, ok := err.(*CorruptionErr) cerr, ok := err.(*CorruptionErr)
if !ok { if !ok {
return errors.New("cannot handle error") return errors.Wrap(origErr, "cannot handle error")
} }
if cerr.Segment < 0 { if cerr.Segment < 0 {
return errors.New("corruption error does not specify position") return errors.New("corruption error does not specify position")

View File

@ -23,6 +23,7 @@ import (
"os" "os"
"testing" "testing"
"github.com/pkg/errors"
"github.com/prometheus/tsdb/testutil" "github.com/prometheus/tsdb/testutil"
) )
@ -286,8 +287,8 @@ func TestWAL_Repair(t *testing.T) {
for r.Next() { for r.Next() {
} }
testutil.NotOk(t, r.Err()) testutil.NotOk(t, r.Err())
testutil.Ok(t, w.Repair(r.Err())) testutil.Ok(t, w.Repair(r.Err()))
testutil.Ok(t, w.Repair(errors.Wrap(r.Err(), "err"))) // See https://github.com/prometheus/prometheus/issues/4603
sr, err = NewSegmentsReader(dir) sr, err = NewSegmentsReader(dir)
testutil.Ok(t, err) testutil.Ok(t, err)