Include file path in errors from PartialDriver.ReadUp() and ReadDown() (#421)

* Include file path in errors from PartialDriver.ReadUp() and ReadDown()

* Use errors.Is(...) instead of os.Is...() in migrate.go: https://github.com/golang/go/issues/41122
This commit is contained in:
Roman Leventov
2020-08-29 16:44:38 -07:00
committed by GitHub
parent b6feedc5d7
commit 28ff5bd316
5 changed files with 45 additions and 23 deletions
+12 -11
View File
@@ -487,7 +487,7 @@ func (m *Migrate) read(from int, to int, ret chan<- interface{}) {
}
prev, err := m.sourceDrv.Prev(suint(from))
if os.IsNotExist(err) && to == -1 {
if errors.Is(err, os.ErrNotExist) && to == -1 {
// apply nil migration
migr, err := m.newMigration(suint(from), -1)
if err != nil {
@@ -580,7 +580,7 @@ func (m *Migrate) readUp(from int, limit int, ret chan<- interface{}) {
// apply next migration
next, err := m.sourceDrv.Next(suint(from))
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
// no limit, but no migrations applied?
if limit == -1 && count == 0 {
ret <- ErrNoChange
@@ -666,7 +666,7 @@ func (m *Migrate) readDown(from int, limit int, ret chan<- interface{}) {
}
prev, err := m.sourceDrv.Prev(suint(from))
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
// no limit or haven't reached limit, apply "first" migration
if limit == -1 || limit-count > 0 {
firstVersion, err := m.sourceDrv.First()
@@ -785,9 +785,9 @@ func (m *Migrate) versionExists(version uint) (result error) {
}
}()
}
if os.IsExist(err) {
if errors.Is(err, os.ErrExist) {
return nil
} else if !os.IsNotExist(err) {
} else if !errors.Is(err, os.ErrNotExist) {
return err
}
@@ -800,14 +800,15 @@ func (m *Migrate) versionExists(version uint) (result error) {
}
}()
}
if os.IsExist(err) {
if errors.Is(err, os.ErrExist) {
return nil
} else if !os.IsNotExist(err) {
} else if !errors.Is(err, os.ErrNotExist) {
return err
}
m.logErr(fmt.Errorf("no migration found for version %d", version))
return os.ErrNotExist
err = fmt.Errorf("no migration found for version %d: %w", version, err)
m.logErr(err)
return err
}
// stop returns true if no more migrations should be run against the database
@@ -835,7 +836,7 @@ func (m *Migrate) newMigration(version uint, targetVersion int) (*Migration, err
if targetVersion >= int(version) {
r, identifier, err := m.sourceDrv.ReadUp(version)
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
// create "empty" migration
migr, err = NewMigration(nil, "", version, targetVersion)
if err != nil {
@@ -855,7 +856,7 @@ func (m *Migrate) newMigration(version uint, targetVersion int) (*Migration, err
} else {
r, identifier, err := m.sourceDrv.ReadDown(version)
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
// create "empty" migration
migr, err = NewMigration(nil, "", version, targetVersion)
if err != nil {
+6 -5
View File
@@ -3,6 +3,7 @@ package migrate
import (
"bytes"
"database/sql"
"errors"
"io/ioutil"
"log"
"os"
@@ -468,7 +469,7 @@ func TestMigrate(t *testing.T) {
for i, v := range tt {
err := m.Migrate(v.version)
if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) ||
if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) ||
(v.expectErr != os.ErrNotExist && err != v.expectErr) {
t.Errorf("expected err %v, got %v, in %v", v.expectErr, err, i)
@@ -731,7 +732,7 @@ func TestSteps(t *testing.T) {
for i, v := range tt {
err := m.Steps(v.steps)
if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) ||
if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) ||
(v.expectErr != os.ErrNotExist && err != v.expectErr) {
t.Errorf("expected err %v, got %v, in %v", v.expectErr, err, i)
@@ -1143,7 +1144,7 @@ func TestRead(t *testing.T) {
go m.read(v.from, v.to, ret)
migrations, err := migrationsFromChannel(ret)
if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) ||
if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) ||
(v.expectErr != os.ErrNotExist && v.expectErr != err) {
t.Errorf("expected %v, got %v, in %v", v.expectErr, err, i)
t.Logf("%v, in %v", migrations, i)
@@ -1220,7 +1221,7 @@ func TestReadUp(t *testing.T) {
go m.readUp(v.from, v.limit, ret)
migrations, err := migrationsFromChannel(ret)
if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) ||
if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) ||
(v.expectErr != os.ErrNotExist && v.expectErr != err) {
t.Errorf("expected %v, got %v, in %v", v.expectErr, err, i)
t.Logf("%v, in %v", migrations, i)
@@ -1297,7 +1298,7 @@ func TestReadDown(t *testing.T) {
go m.readDown(v.from, v.limit, ret)
migrations, err := migrationsFromChannel(ret)
if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) ||
if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) ||
(v.expectErr != os.ErrNotExist && v.expectErr != err) {
t.Errorf("expected %v, got %v, in %v", v.expectErr, err, i)
t.Logf("%v, in %v", migrations, i)
+2 -1
View File
@@ -1,6 +1,7 @@
package file
import (
"errors"
"fmt"
"io/ioutil"
"os"
@@ -235,7 +236,7 @@ func BenchmarkNext(b *testing.B) {
b.ResetTimer()
v, err := d.First()
for n := 0; n < b.N; n++ {
for !os.IsNotExist(err) {
for !errors.Is(err, os.ErrNotExist) {
v, err = d.Next(v)
}
}
+20 -2
View File
@@ -1,6 +1,7 @@
package httpfs
import (
"errors"
"io"
"net/http"
"os"
@@ -108,7 +109,7 @@ func (p *PartialDriver) Next(version uint) (nextVersion uint, err error) {
// ReadUp is part of source.Driver interface implementation.
func (p *PartialDriver) ReadUp(version uint) (r io.ReadCloser, identifier string, err error) {
if m, ok := p.migrations.Up(version); ok {
body, err := p.fs.Open(path.Join(p.path, m.Raw))
body, err := p.open(path.Join(p.path, m.Raw))
if err != nil {
return nil, "", err
}
@@ -124,7 +125,7 @@ func (p *PartialDriver) ReadUp(version uint) (r io.ReadCloser, identifier string
// ReadDown is part of source.Driver interface implementation.
func (p *PartialDriver) ReadDown(version uint) (r io.ReadCloser, identifier string, err error) {
if m, ok := p.migrations.Down(version); ok {
body, err := p.fs.Open(path.Join(p.path, m.Raw))
body, err := p.open(path.Join(p.path, m.Raw))
if err != nil {
return nil, "", err
}
@@ -136,3 +137,20 @@ func (p *PartialDriver) ReadDown(version uint) (r io.ReadCloser, identifier stri
Err: os.ErrNotExist,
}
}
func (p *PartialDriver) open(path string) (http.File, error) {
f, err := p.fs.Open(path)
if err == nil {
return f, nil
}
// Some non-standard file systems may return errors that don't include the path, that
// makes debugging harder.
if !errors.As(err, new(*os.PathError)) {
err = &os.PathError{
Op: "open",
Path: path,
Err: err,
}
}
return nil, err
}
+5 -4
View File
@@ -4,6 +4,7 @@
package testing
import (
"errors"
"os"
"testing"
@@ -56,7 +57,7 @@ func TestPrev(t *testing.T, d source.Driver) {
for i, v := range tt {
pv, err := d.Prev(v.version)
if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) && v.expectErr != err {
if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) && v.expectErr != err {
t.Errorf("Prev: expected %v, got %v, in %v", v.expectErr, err, i)
}
if err == nil && v.expectPrevVersion != pv {
@@ -85,7 +86,7 @@ func TestNext(t *testing.T, d source.Driver) {
for i, v := range tt {
nv, err := d.Next(v.version)
if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) && v.expectErr != err {
if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) && v.expectErr != err {
t.Errorf("Next: expected %v, got %v, in %v", v.expectErr, err, i)
}
if err == nil && v.expectNextVersion != nv {
@@ -113,7 +114,7 @@ func TestReadUp(t *testing.T, d source.Driver) {
for i, v := range tt {
up, identifier, err := d.ReadUp(v.version)
if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) ||
if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) ||
(v.expectErr != os.ErrNotExist && err != v.expectErr) {
t.Errorf("expected %v, got %v, in %v", v.expectErr, err, i)
@@ -150,7 +151,7 @@ func TestReadDown(t *testing.T, d source.Driver) {
for i, v := range tt {
down, identifier, err := d.ReadDown(v.version)
if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) ||
if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) ||
(v.expectErr != os.ErrNotExist && err != v.expectErr) {
t.Errorf("expected %v, got %v, in %v", v.expectErr, err, i)