Browse Source

fix:The WithGlobalTx method returns the exception caught by recover (#849)

* fix:The WithGlobalTx method returns the exception caught by recover

* fix:add case of panic non-error type;WithGlobalTx return a specific exception

* fix:Combine error judgments into a single conditional statement to make the code more readable.

---------

Co-authored-by: FengZhang <zfcode@qq.com>
master
tanzegen GitHub 1 month ago
parent
commit
22f5f7c27b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 2 deletions
  1. +12
    -2
      pkg/tm/transaction_executor.go
  2. +34
    -0
      pkg/tm/transaction_executor_test.go

+ 12
- 2
pkg/tm/transaction_executor.go View File

@@ -73,8 +73,18 @@ func WithGlobalTx(ctx context.Context, gc *GtxConfig, business CallbackWithCtx)
}
}

if re != nil || err != nil {
re = fmt.Errorf("first phase error: %v, second phase error: %v", re, err)
if re == nil {
if deferErr != nil {
// if deferErr is not an error, then convert it to error
// this is because panic may be caused by non-error type e.g. panic("some string")
// so we need to convert it to error type
if _, ok := deferErr.(error); !ok {
deferErr = fmt.Errorf("%v", deferErr)
}
re = deferErr.(error)
} else if err != nil {
re = err
}
}
}()



+ 34
- 0
pkg/tm/transaction_executor_test.go View File

@@ -382,6 +382,12 @@ func TestWithGlobalTx(t *testing.T) {
callbackNil := func(ctx context.Context) error {
return nil
}
callbackPanicError := func(ctx context.Context) error {
panic(errors.New("mock callback panic error"))
}
callbackPanicString := func(ctx context.Context) error {
panic("mock callback panic string")
}

type testCase struct {
GtxConfig *GtxConfig
@@ -458,6 +464,34 @@ func TestWithGlobalTx(t *testing.T) {
},
},

// case callback panic string
{
GtxConfig: &GtxConfig{
Name: "MockGtxConfig",
},
callbackErr: true,
callback: callbackPanicString,
occurError: true,
errMessage: "mock callback panic string",
mockBeginTarget: begin,
mockBeginFunc: func(ctx context.Context, gc *GtxConfig) error {
return nil
},
},

// case callback panic error
{
GtxConfig: &GtxConfig{
Name: "MockGtxConfig",
},
callbackErr: true,
callback: callbackPanicError,
mockBeginTarget: begin,
mockBeginFunc: func(ctx context.Context, gc *GtxConfig) error {
return nil
},
},

// case second mock error
{
GtxConfig: &GtxConfig{


Loading…
Cancel
Save