github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/xerrors/operation_test.go (about) 1 package xerrors 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 "github.com/ydb-platform/ydb-go-genproto/protos/Ydb" 9 "github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Issue" 10 ) 11 12 func TestIsOperationError(t *testing.T) { 13 for _, tt := range []struct { 14 err error 15 codes []Ydb.StatusIds_StatusCode 16 match bool 17 }{ 18 // check only operation error with any ydb status code 19 { 20 err: &operationError{code: Ydb.StatusIds_BAD_REQUEST}, 21 match: true, 22 }, 23 { 24 err: fmt.Errorf("wrapped: %w", &operationError{code: Ydb.StatusIds_BAD_REQUEST}), 25 match: true, 26 }, 27 { 28 err: Join( 29 fmt.Errorf("test"), 30 &operationError{code: Ydb.StatusIds_BAD_REQUEST}, 31 Retryable(fmt.Errorf("test")), 32 ), 33 match: true, 34 }, 35 // match ydb status code 36 { 37 err: &operationError{code: Ydb.StatusIds_BAD_REQUEST}, 38 codes: []Ydb.StatusIds_StatusCode{Ydb.StatusIds_BAD_REQUEST}, 39 match: true, 40 }, 41 { 42 err: fmt.Errorf("wrapped: %w", &operationError{code: Ydb.StatusIds_BAD_REQUEST}), 43 codes: []Ydb.StatusIds_StatusCode{Ydb.StatusIds_BAD_REQUEST}, 44 match: true, 45 }, 46 { 47 err: Join( 48 fmt.Errorf("test"), 49 &operationError{code: Ydb.StatusIds_BAD_REQUEST}, 50 Retryable(fmt.Errorf("test")), 51 ), 52 codes: []Ydb.StatusIds_StatusCode{Ydb.StatusIds_BAD_REQUEST}, 53 match: true, 54 }, 55 // no match ydb status code 56 { 57 err: &operationError{code: Ydb.StatusIds_BAD_REQUEST}, 58 codes: []Ydb.StatusIds_StatusCode{Ydb.StatusIds_ABORTED}, 59 match: false, 60 }, 61 { 62 err: fmt.Errorf("wrapped: %w", &operationError{code: Ydb.StatusIds_BAD_REQUEST}), 63 codes: []Ydb.StatusIds_StatusCode{Ydb.StatusIds_ABORTED}, 64 match: false, 65 }, 66 { 67 err: Join( 68 fmt.Errorf("test"), 69 &operationError{code: Ydb.StatusIds_BAD_REQUEST}, 70 Retryable(fmt.Errorf("test")), 71 ), 72 codes: []Ydb.StatusIds_StatusCode{Ydb.StatusIds_ABORTED}, 73 match: false, 74 }, 75 } { 76 t.Run("", func(t *testing.T) { 77 require.Equal(t, tt.match, IsOperationError(tt.err, tt.codes...)) 78 }) 79 } 80 } 81 82 func TestIsOperationErrorTransactionLocksInvalidated(t *testing.T) { 83 for _, tt := range [...]struct { 84 err error 85 isTLI bool 86 }{ 87 { 88 err: Operation( 89 WithStatusCode(Ydb.StatusIds_ABORTED), 90 WithIssues([]*Ydb_Issue.IssueMessage{{ 91 IssueCode: issueCodeTransactionLocksInvalidated, 92 }}), 93 ), 94 isTLI: true, 95 }, 96 { 97 err: Operation( 98 WithStatusCode(Ydb.StatusIds_OVERLOADED), 99 WithIssues([]*Ydb_Issue.IssueMessage{{ 100 IssueCode: issueCodeTransactionLocksInvalidated, 101 }}), 102 ), 103 isTLI: false, 104 }, 105 { 106 err: Operation( 107 WithStatusCode(Ydb.StatusIds_ABORTED), 108 ), 109 isTLI: false, 110 }, 111 { 112 err: Operation( 113 WithStatusCode(Ydb.StatusIds_ABORTED), 114 WithIssues([]*Ydb_Issue.IssueMessage{{ 115 Issues: []*Ydb_Issue.IssueMessage{{ 116 IssueCode: issueCodeTransactionLocksInvalidated, 117 }}, 118 }}), 119 ), 120 isTLI: true, 121 }, 122 } { 123 t.Run("", func(t *testing.T) { 124 require.Equal(t, tt.isTLI, IsOperationErrorTransactionLocksInvalidated(tt.err)) 125 }) 126 } 127 } 128 129 func Test_operationError_Error(t *testing.T) { 130 for _, tt := range []struct { 131 err error 132 text string 133 }{ 134 { 135 err: Operation(WithStatusCode(Ydb.StatusIds_BAD_REQUEST), WithAddress("localhost")), 136 text: "operation/BAD_REQUEST (code = 400010, address = localhost)", 137 }, 138 { 139 err: Operation(WithStatusCode(Ydb.StatusIds_BAD_REQUEST)), 140 text: "operation/BAD_REQUEST (code = 400010)", 141 }, 142 { 143 err: Operation(WithStatusCode(Ydb.StatusIds_BAD_SESSION)), 144 text: "operation/BAD_SESSION (code = 400100)", 145 }, 146 { 147 err: Operation(WithStatusCode(Ydb.StatusIds_PRECONDITION_FAILED), WithIssues([]*Ydb_Issue.IssueMessage{ 148 { 149 Message: "issue one", 150 IssueCode: 1, 151 Position: &Ydb_Issue.IssueMessage_Position{ 152 Row: 15, 153 Column: 3, 154 File: "", 155 }, 156 }, 157 { 158 Message: "issue two", 159 IssueCode: 2, 160 Issues: []*Ydb_Issue.IssueMessage{ 161 { 162 Message: "issue three", 163 IssueCode: 3, 164 Position: &Ydb_Issue.IssueMessage_Position{ 165 Row: 16, 166 Column: 4, 167 File: "test.yql", 168 }, 169 }, 170 { 171 Message: "issue four", 172 IssueCode: 4, 173 }, 174 }, 175 }, 176 })), 177 text: "operation/PRECONDITION_FAILED (code = 400120, issues = [{15:3 => #1 'issue one'},{#2 'issue two' [{test.yql:16:4 => #3 'issue three'},{#4 'issue four'}]}])", //nolint:lll 178 }, 179 } { 180 t.Run("", func(t *testing.T) { 181 require.Equal(t, tt.text, tt.err.Error()) 182 }) 183 } 184 }