This is an automated email from the ASF dual-hosted git repository.

thunguo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-seata-go.git


The following commit(s) were added to refs/heads/master by this push:
     new 55e99b41 fix: before hooks error handling (#1096)
55e99b41 is described below

commit 55e99b41024d9b907a3105fcef6f1d03b5ab4aa4
Author: Oxidaner <[email protected]>
AuthorDate: Wed Apr 22 19:23:32 2026 +0800

    fix: before hooks error handling (#1096)
    
    * fix: propagate before hook errors in at executors
    
    * Update pkg/datasource/sql/exec/at/at_executor_test.go
    
    Co-authored-by: Copilot <[email protected]>
    
    ---------
    
    Co-authored-by: ThunGuo <[email protected]>
    Co-authored-by: Copilot <[email protected]>
---
 pkg/datasource/sql/exec/at/at_executor_test.go     | 86 ++++++++++++++++++++++
 pkg/datasource/sql/exec/at/delete_executor.go      |  4 +-
 pkg/datasource/sql/exec/at/insert_executor.go      |  4 +-
 .../sql/exec/at/insert_on_update_executor.go       |  4 +-
 .../sql/exec/at/multi_delete_executor.go           |  4 +-
 pkg/datasource/sql/exec/at/multi_executor.go       |  4 +-
 pkg/datasource/sql/exec/at/multi_update_excutor.go |  4 +-
 .../sql/exec/at/select_for_update_executor.go      |  4 +-
 pkg/datasource/sql/exec/at/update_executor.go      |  4 +-
 pkg/datasource/sql/exec/at/update_join_executor.go |  4 +-
 10 files changed, 113 insertions(+), 9 deletions(-)

diff --git a/pkg/datasource/sql/exec/at/at_executor_test.go 
b/pkg/datasource/sql/exec/at/at_executor_test.go
index 10b9054e..c6ade935 100644
--- a/pkg/datasource/sql/exec/at/at_executor_test.go
+++ b/pkg/datasource/sql/exec/at/at_executor_test.go
@@ -358,6 +358,92 @@ func TestATExecutor_ExecWithValue_ParserError(t 
*testing.T) {
        assert.Nil(t, result, "result should be nil on error")
 }
 
+func TestATExecutors_ExecContext_BeforeHookError(t *testing.T) {
+       beforeErr := fmt.Errorf("before hook error")
+
+       tests := []struct {
+               name        string
+               newExecutor func(hooks []exec.SQLHook) executor
+       }{
+               {
+                       name: "insert",
+                       newExecutor: func(hooks []exec.SQLHook) executor {
+                               return &insertExecutor{baseExecutor: 
baseExecutor{hooks: hooks}, execContext: &types.ExecContext{}}
+                       },
+               },
+               {
+                       name: "insert on update",
+                       newExecutor: func(hooks []exec.SQLHook) executor {
+                               return &insertOnUpdateExecutor{baseExecutor: 
baseExecutor{hooks: hooks}, execContext: &types.ExecContext{}}
+                       },
+               },
+               {
+                       name: "delete",
+                       newExecutor: func(hooks []exec.SQLHook) executor {
+                               return deleteExecutor{baseExecutor: 
baseExecutor{hooks: hooks}, execContext: &types.ExecContext{}}
+                       },
+               },
+               {
+                       name: "multi delete",
+                       newExecutor: func(hooks []exec.SQLHook) executor {
+                               return &multiDeleteExecutor{baseExecutor: 
baseExecutor{hooks: hooks}, execContext: &types.ExecContext{}}
+                       },
+               },
+               {
+                       name: "multi",
+                       newExecutor: func(hooks []exec.SQLHook) executor {
+                               return &multiExecutor{baseExecutor: 
baseExecutor{hooks: hooks}, execContext: &types.ExecContext{}}
+                       },
+               },
+               {
+                       name: "multi update",
+                       newExecutor: func(hooks []exec.SQLHook) executor {
+                               return &multiUpdateExecutor{baseExecutor: 
baseExecutor{hooks: hooks}, execContext: &types.ExecContext{}}
+                       },
+               },
+               {
+                       name: "select for update",
+                       newExecutor: func(hooks []exec.SQLHook) executor {
+                               return &selectForUpdateExecutor{baseExecutor: 
baseExecutor{hooks: hooks}, execContext: &types.ExecContext{}}
+                       },
+               },
+               {
+                       name: "update",
+                       newExecutor: func(hooks []exec.SQLHook) executor {
+                               return &updateExecutor{baseExecutor: 
baseExecutor{hooks: hooks}, execContext: &types.ExecContext{}}
+                       },
+               },
+               {
+                       name: "update join",
+                       newExecutor: func(hooks []exec.SQLHook) executor {
+                               return &updateJoinExecutor{baseExecutor: 
baseExecutor{hooks: hooks}, execContext: &types.ExecContext{}}
+                       },
+               },
+       }
+
+       for _, tt := range tests {
+               tt := tt
+               t.Run(tt.name, func(t *testing.T) {
+                       hook := &mockSQLHook{beforeError: beforeErr}
+                       callbackCount := 0
+
+                       result, err := 
tt.newExecutor([]exec.SQLHook{hook}).ExecContext(
+                               context.Background(),
+                               func(ctx context.Context, query string, args 
[]driver.NamedValue) (types.ExecResult, error) {
+                                       callbackCount++
+                                       return &mockExecResult{rowsAffected: 
1}, nil
+                               },
+                       )
+
+                       assert.ErrorIs(t, err, beforeErr)
+                       assert.Nil(t, result)
+                       assert.Equal(t, 1, hook.beforeCallCount)
+                       assert.Equal(t, 0, hook.afterCallCount)
+                       assert.Equal(t, 0, callbackCount)
+               })
+       }
+}
+
 type mockSQLHook struct {
        sqlType         types.SQLType
        beforeCallCount int
diff --git a/pkg/datasource/sql/exec/at/delete_executor.go 
b/pkg/datasource/sql/exec/at/delete_executor.go
index 1fb02c81..959f5e9f 100644
--- a/pkg/datasource/sql/exec/at/delete_executor.go
+++ b/pkg/datasource/sql/exec/at/delete_executor.go
@@ -48,7 +48,9 @@ func NewDeleteExecutor(parserCtx *types.ParseContext, 
execContent *types.ExecCon
 
 // ExecContext exec SQL, and generate before image and after image
 func (d deleteExecutor) ExecContext(ctx context.Context, f 
exec.CallbackWithNamedValue) (types.ExecResult, error) {
-       d.beforeHooks(ctx, d.execContext)
+       if err := d.beforeHooks(ctx, d.execContext); err != nil {
+               return nil, err
+       }
        defer func() {
                d.afterHooks(ctx, d.execContext)
        }()
diff --git a/pkg/datasource/sql/exec/at/insert_executor.go 
b/pkg/datasource/sql/exec/at/insert_executor.go
index 12e83c64..5fddc313 100644
--- a/pkg/datasource/sql/exec/at/insert_executor.go
+++ b/pkg/datasource/sql/exec/at/insert_executor.go
@@ -52,7 +52,9 @@ func NewInsertExecutor(parserCtx *types.ParseContext, 
execContent *types.ExecCon
 }
 
 func (i *insertExecutor) ExecContext(ctx context.Context, f 
exec.CallbackWithNamedValue) (types.ExecResult, error) {
-       i.beforeHooks(ctx, i.execContext)
+       if err := i.beforeHooks(ctx, i.execContext); err != nil {
+               return nil, err
+       }
        defer func() {
                i.afterHooks(ctx, i.execContext)
        }()
diff --git a/pkg/datasource/sql/exec/at/insert_on_update_executor.go 
b/pkg/datasource/sql/exec/at/insert_on_update_executor.go
index ada89562..06f4e74f 100644
--- a/pkg/datasource/sql/exec/at/insert_on_update_executor.go
+++ b/pkg/datasource/sql/exec/at/insert_on_update_executor.go
@@ -54,7 +54,9 @@ func NewInsertOnUpdateExecutor(parserCtx *types.ParseContext, 
execContent *types
 }
 
 func (i *insertOnUpdateExecutor) ExecContext(ctx context.Context, f 
exec.CallbackWithNamedValue) (types.ExecResult, error) {
-       i.beforeHooks(ctx, i.execContext)
+       if err := i.beforeHooks(ctx, i.execContext); err != nil {
+               return nil, err
+       }
        defer func() {
                i.afterHooks(ctx, i.execContext)
        }()
diff --git a/pkg/datasource/sql/exec/at/multi_delete_executor.go 
b/pkg/datasource/sql/exec/at/multi_delete_executor.go
index ccc83184..0ccc9ec1 100644
--- a/pkg/datasource/sql/exec/at/multi_delete_executor.go
+++ b/pkg/datasource/sql/exec/at/multi_delete_executor.go
@@ -40,7 +40,9 @@ type multiDeleteExecutor struct {
 }
 
 func (m *multiDeleteExecutor) ExecContext(ctx context.Context, f 
exec.CallbackWithNamedValue) (types.ExecResult, error) {
-       m.beforeHooks(ctx, m.execContext)
+       if err := m.beforeHooks(ctx, m.execContext); err != nil {
+               return nil, err
+       }
        defer func() {
                m.afterHooks(ctx, m.execContext)
        }()
diff --git a/pkg/datasource/sql/exec/at/multi_executor.go 
b/pkg/datasource/sql/exec/at/multi_executor.go
index 643af12d..8ce53a8e 100644
--- a/pkg/datasource/sql/exec/at/multi_executor.go
+++ b/pkg/datasource/sql/exec/at/multi_executor.go
@@ -39,7 +39,9 @@ func NewMultiExecutor(parserCtx *types.ParseContext, 
execContext *types.ExecCont
 
 // ExecContext exec SQL, and generate before image and after image
 func (m *multiExecutor) ExecContext(ctx context.Context, f 
exec.CallbackWithNamedValue) (types.ExecResult, error) {
-       m.beforeHooks(ctx, m.execContext)
+       if err := m.beforeHooks(ctx, m.execContext); err != nil {
+               return nil, err
+       }
 
        defer func() {
                m.afterHooks(ctx, m.execContext)
diff --git a/pkg/datasource/sql/exec/at/multi_update_excutor.go 
b/pkg/datasource/sql/exec/at/multi_update_excutor.go
index 9a034142..a5382aa0 100644
--- a/pkg/datasource/sql/exec/at/multi_update_excutor.go
+++ b/pkg/datasource/sql/exec/at/multi_update_excutor.go
@@ -55,7 +55,9 @@ func NewMultiUpdateExecutor(parserCtx *types.ParseContext, 
execContext *types.Ex
 
 // ExecContext exec SQL, and generate before image and after image
 func (u *multiUpdateExecutor) ExecContext(ctx context.Context, f 
exec.CallbackWithNamedValue) (types.ExecResult, error) {
-       u.beforeHooks(ctx, u.execContext)
+       if err := u.beforeHooks(ctx, u.execContext); err != nil {
+               return nil, err
+       }
        defer func() {
                u.afterHooks(ctx, u.execContext)
        }()
diff --git a/pkg/datasource/sql/exec/at/select_for_update_executor.go 
b/pkg/datasource/sql/exec/at/select_for_update_executor.go
index 60973eaf..e3b543fb 100644
--- a/pkg/datasource/sql/exec/at/select_for_update_executor.go
+++ b/pkg/datasource/sql/exec/at/select_for_update_executor.go
@@ -73,7 +73,9 @@ func NewSelectForUpdateExecutor(parserCtx 
*types.ParseContext, execContext *type
 }
 
 func (s *selectForUpdateExecutor) ExecContext(ctx context.Context, f 
exec.CallbackWithNamedValue) (types.ExecResult, error) {
-       s.beforeHooks(ctx, s.execContext)
+       if err := s.beforeHooks(ctx, s.execContext); err != nil {
+               return nil, err
+       }
        defer func() {
                s.afterHooks(ctx, s.execContext)
        }()
diff --git a/pkg/datasource/sql/exec/at/update_executor.go 
b/pkg/datasource/sql/exec/at/update_executor.go
index ffd65f56..53419ceb 100644
--- a/pkg/datasource/sql/exec/at/update_executor.go
+++ b/pkg/datasource/sql/exec/at/update_executor.go
@@ -60,7 +60,9 @@ func NewUpdateExecutor(parserCtx *types.ParseContext, 
execContent *types.ExecCon
 
 // ExecContext exec SQL, and generate before image and after image
 func (u *updateExecutor) ExecContext(ctx context.Context, f 
exec.CallbackWithNamedValue) (types.ExecResult, error) {
-       u.beforeHooks(ctx, u.execContext)
+       if err := u.beforeHooks(ctx, u.execContext); err != nil {
+               return nil, err
+       }
        defer func() {
                u.afterHooks(ctx, u.execContext)
        }()
diff --git a/pkg/datasource/sql/exec/at/update_join_executor.go 
b/pkg/datasource/sql/exec/at/update_join_executor.go
index 093e82c8..4b0b874d 100644
--- a/pkg/datasource/sql/exec/at/update_join_executor.go
+++ b/pkg/datasource/sql/exec/at/update_join_executor.go
@@ -66,7 +66,9 @@ func NewUpdateJoinExecutor(parserCtx *types.ParseContext, 
execContent *types.Exe
 
 // ExecContext exec SQL, and generate before image and after image
 func (u *updateJoinExecutor) ExecContext(ctx context.Context, f 
exec.CallbackWithNamedValue) (types.ExecResult, error) {
-       u.beforeHooks(ctx, u.execContext)
+       if err := u.beforeHooks(ctx, u.execContext); err != nil {
+               return nil, err
+       }
        defer func() {
                u.afterHooks(ctx, u.execContext)
        }()


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to