diff --git a/leveldb/errors/errors.go b/leveldb/errors/errors.go index 8d6146b6..9bb55c66 100644 --- a/leveldb/errors/errors.go +++ b/leveldb/errors/errors.go @@ -10,6 +10,7 @@ package errors import ( "errors" "fmt" + "strings" "github.com/syndtr/goleveldb/leveldb/storage" "github.com/syndtr/goleveldb/leveldb/util" @@ -76,3 +77,15 @@ func SetFd(err error, fd storage.FileDesc) error { } return err } + +// IsUnrecoverableError Determine whether there is no need to restart the error that can be repaired +// for example, the disk is full. This error is a fixable error +func IsUnrecoverableError(err error) bool { + if err == nil { + return false + } + if strings.Contains(err.Error(), "no space left on device") { + return false + } + return true +} diff --git a/leveldb/journal/journal.go b/leveldb/journal/journal.go index d094c3d0..1f5e06c1 100644 --- a/leveldb/journal/journal.go +++ b/leveldb/journal/journal.go @@ -407,7 +407,7 @@ func (w *Writer) writeBlock() { // writePending finishes the current journal and writes the buffer to the // underlying writer. func (w *Writer) writePending() { - if w.err != nil { + if errors.IsUnrecoverableError(w.err) { return } if w.pending { @@ -422,7 +422,7 @@ func (w *Writer) writePending() { func (w *Writer) Close() error { w.seq++ w.writePending() - if w.err != nil { + if errors.IsUnrecoverableError(w.err) { return w.err } w.err = errors.New("leveldb/journal: closed Writer") @@ -434,7 +434,7 @@ func (w *Writer) Close() error { func (w *Writer) Flush() error { w.seq++ w.writePending() - if w.err != nil { + if errors.IsUnrecoverableError(w.err) { return w.err } if w.f != nil { @@ -467,7 +467,7 @@ func (w *Writer) Reset(writer io.Writer) (err error) { // after the next Close, Flush or Next call, and should no longer be used. func (w *Writer) Next() (io.Writer, error) { w.seq++ - if w.err != nil { + if errors.IsUnrecoverableError(w.err) { return nil, w.err } if w.pending { @@ -501,7 +501,7 @@ func (x singleWriter) Write(p []byte) (int, error) { if w.seq != x.seq { return 0, errors.New("leveldb/journal: stale writer") } - if w.err != nil { + if errors.IsUnrecoverableError(w.err) { return 0, w.err } n0 := len(p) diff --git a/leveldb/table/writer.go b/leveldb/table/writer.go index fda697bd..1e80c7a3 100644 --- a/leveldb/table/writer.go +++ b/leveldb/table/writer.go @@ -15,6 +15,7 @@ import ( "github.com/golang/snappy" "github.com/syndtr/goleveldb/leveldb/comparer" + lerrors "github.com/syndtr/goleveldb/leveldb/errors" "github.com/syndtr/goleveldb/leveldb/filter" "github.com/syndtr/goleveldb/leveldb/opt" "github.com/syndtr/goleveldb/leveldb/util" @@ -236,7 +237,7 @@ func (w *Writer) finishBlock() error { // // It is safe to modify the contents of the arguments after Append returns. func (w *Writer) Append(key, value []byte) error { - if w.err != nil { + if lerrors.IsUnrecoverableError(w.err) { return w.err } if w.nEntries > 0 && w.cmp.Compare(w.dataBlock.prevKey, key) >= 0 { @@ -285,7 +286,7 @@ func (w *Writer) BytesLen() int { // after Close, but calling BlocksLen, EntriesLen and BytesLen // is still possible. func (w *Writer) Close() error { - if w.err != nil { + if lerrors.IsUnrecoverableError(w.err) { return w.err }