-
Notifications
You must be signed in to change notification settings - Fork 373
Expand file tree
/
Copy patherrors_test.go
More file actions
112 lines (94 loc) · 3.44 KB
/
errors_test.go
File metadata and controls
112 lines (94 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package common
import (
"fmt"
"testing"
"github.com/go-sql-driver/mysql"
"github.com/stretchr/testify/require"
dscommon "github.com/authzed/spicedb/internal/datastore/common"
)
func TestIsMissingTableError(t *testing.T) {
t.Run("returns true for missing table error", func(t *testing.T) {
mysqlErr := &mysql.MySQLError{
Number: mysqlMissingTableErrorNumber,
Message: "Table 'spicedb.caveat' doesn't exist",
}
require.True(t, IsMissingTableError(mysqlErr))
})
t.Run("returns false for other mysql errors", func(t *testing.T) {
mysqlErr := &mysql.MySQLError{
Number: 1062, // Duplicate entry error
Message: "Duplicate entry '1' for key 'PRIMARY'",
}
require.False(t, IsMissingTableError(mysqlErr))
})
t.Run("returns false for non-mysql errors", func(t *testing.T) {
err := fmt.Errorf("some other error")
require.False(t, IsMissingTableError(err))
})
t.Run("returns false for nil error", func(t *testing.T) {
require.False(t, IsMissingTableError(nil))
})
t.Run("returns true for wrapped missing table error", func(t *testing.T) {
mysqlErr := &mysql.MySQLError{
Number: mysqlMissingTableErrorNumber,
Message: "Table 'spicedb.caveat' doesn't exist",
}
wrappedErr := fmt.Errorf("query failed: %w", mysqlErr)
require.True(t, IsMissingTableError(wrappedErr))
})
}
func TestWrapMissingTableError(t *testing.T) {
t.Run("wraps missing table error", func(t *testing.T) {
mysqlErr := &mysql.MySQLError{
Number: mysqlMissingTableErrorNumber,
Message: "Table 'spicedb.caveat' doesn't exist",
}
wrapped := WrapMissingTableError(mysqlErr)
require.Error(t, wrapped)
var schemaErr dscommon.SchemaNotInitializedError
require.ErrorAs(t, wrapped, &schemaErr)
require.Contains(t, wrapped.Error(), "spicedb datastore migrate")
})
t.Run("returns nil for non-missing-table errors", func(t *testing.T) {
mysqlErr := &mysql.MySQLError{
Number: 1062, // Duplicate entry error
Message: "Duplicate entry '1' for key 'PRIMARY'",
}
require.NoError(t, WrapMissingTableError(mysqlErr))
})
t.Run("returns nil for non-mysql errors", func(t *testing.T) {
err := fmt.Errorf("some other error")
require.NoError(t, WrapMissingTableError(err))
})
t.Run("returns nil for nil error", func(t *testing.T) {
require.NoError(t, WrapMissingTableError(nil))
})
t.Run("preserves original error in chain", func(t *testing.T) {
mysqlErr := &mysql.MySQLError{
Number: mysqlMissingTableErrorNumber,
Message: "Table 'spicedb.caveat' doesn't exist",
}
wrapped := WrapMissingTableError(mysqlErr)
require.Error(t, wrapped)
// The original mysql error should be accessible via unwrapping
var foundMySQLErr *mysql.MySQLError
require.ErrorAs(t, wrapped, &foundMySQLErr)
require.Equal(t, uint16(mysqlMissingTableErrorNumber), foundMySQLErr.Number)
})
t.Run("does not double-wrap already wrapped errors", func(t *testing.T) {
mysqlErr := &mysql.MySQLError{
Number: mysqlMissingTableErrorNumber,
Message: "Table 'spicedb.caveat' doesn't exist",
}
// First wrap
wrapped := WrapMissingTableError(mysqlErr)
require.Error(t, wrapped)
// Second wrap should return the already-wrapped error (preserving it through call chain)
doubleWrapped := WrapMissingTableError(wrapped)
require.Error(t, doubleWrapped)
require.Equal(t, wrapped, doubleWrapped)
// Should still be detectable as SchemaNotInitializedError
var schemaErr dscommon.SchemaNotInitializedError
require.ErrorAs(t, doubleWrapped, &schemaErr)
})
}