Skip to content

Commit 24db333

Browse files
authored
Feat/manager from context return error (#544)
* feat: ManagerFromContext returns (Manager, error) instead of Manager BREAKING CHANGE: ManagerFromContext now returns (Manager, error) tuple. Returns ErrNoManagerFoundInContext when manager is not found in context. - Update ManagerFromContext signature in manager.go - Update all callers in shortcuts.go, scope.go, middleware.go - Add ErrNoManagerFoundInContext error definition in errors.go * wip
1 parent 61b3af6 commit 24db333

File tree

5 files changed

+39
-12
lines changed

5 files changed

+39
-12
lines changed

errors.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ var (
3535

3636
// ErrNoStatementFound is an error that is returned when the statement is not found.
3737
ErrNoStatementFound = errors.New("no statement found")
38+
39+
// ErrNoManagerFoundInContext is an error that is returned when the manager is not found in context.
40+
ErrNoManagerFoundInContext = errors.New("no manager found in context")
3841
)
3942

4043
// nodeUnclosedError is an error that is returned when the node is not closed.

manager.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,12 @@ func managerFromContext(ctx context.Context) (Manager, bool) {
149149
}
150150

151151
// ManagerFromContext returns the Manager from the context.
152-
func ManagerFromContext(ctx context.Context) Manager {
153-
manager, _ := managerFromContext(ctx)
154-
return manager
152+
func ManagerFromContext(ctx context.Context) (Manager, error) {
153+
manager, ok := managerFromContext(ctx)
154+
if !ok {
155+
return nil, ErrNoManagerFoundInContext
156+
}
157+
return manager, nil
155158
}
156159

157160
// ContextWithManager returns a new context with the given Manager.

middleware.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ func (m *useGeneratedKeysMiddleware) ExecContext(stmt Statement, configuration C
375375

376376
// isInTransaction checks if the current context is within a transaction
377377
func isInTransaction(ctx context.Context) bool {
378-
manager := ManagerFromContext(ctx)
378+
manager, _ := ManagerFromContext(ctx)
379379
return IsTxManager(manager)
380380
}
381381

@@ -448,7 +448,7 @@ func (t *TxSensitiveDataSourceSwitchMiddleware) chooseDataSourceName(dataSourceN
448448
// - The manager is not an Engine
449449
// - The chosen datasource is the same as the requested one
450450
func (t *TxSensitiveDataSourceSwitchMiddleware) switchDataSource(ctx context.Context, dataSourceName string) (context.Context, error) {
451-
manager := ManagerFromContext(ctx)
451+
manager, _ := ManagerFromContext(ctx)
452452
engine, ok := manager.(*Engine)
453453
if !ok {
454454
// In current implementation, this case should never happen.

scope.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ var ErrCommitOnSpecific = tx.ErrCommitOnSpecific
4848
// // handle error
4949
// }
5050
func Transaction(ctx context.Context, handler func(ctx context.Context) error, opts ...tx.TransactionOptionFunc) (err error) {
51-
manager := ManagerFromContext(ctx)
51+
manager, err := ManagerFromContext(ctx)
52+
if err != nil {
53+
return err
54+
}
5255
engine, ok := manager.(*Engine)
5356
if !ok {
5457
return ErrInvalidManager
@@ -71,7 +74,10 @@ func Transaction(ctx context.Context, handler func(ctx context.Context) error, o
7174
// If the manager is a TxManager, it will execute the handler within the existing transaction.
7275
// Otherwise, it will create a new transaction and execute the handler within the new transaction.
7376
func NestedTransaction(ctx context.Context, handler func(ctx context.Context) error, opts ...tx.TransactionOptionFunc) (err error) {
74-
manager := ManagerFromContext(ctx)
77+
manager, err := ManagerFromContext(ctx)
78+
if err != nil {
79+
return err
80+
}
7581
if IsTxManager(manager) {
7682
return handler(ctx)
7783
}

shortcuts.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,32 @@ import (
2727
// QueryContext executes a query with the provided context and scans a single result into T.
2828
// (ctx must contain a Manager via ManagerFromContext)
2929
func QueryContext[T any](ctx context.Context, statement, param any) (result T, err error) {
30-
manager := ManagerFromContext(ctx)
30+
manager, err := ManagerFromContext(ctx)
31+
if err != nil {
32+
return result, err
33+
}
3134
executor := NewGenericManager[T](manager).Object(statement)
3235
return executor.QueryContext(ctx, param)
3336
}
3437

3538
// ExecContext executes a statement that does not return rows and returns a sql.Result.
3639
// (ctx must contain a Manager via ManagerFromContext)
3740
func ExecContext(ctx context.Context, statement, param any) (result sql.Result, err error) {
38-
manager := ManagerFromContext(ctx)
41+
manager, err := ManagerFromContext(ctx)
42+
if err != nil {
43+
return nil, err
44+
}
3945
executor := manager.Object(statement)
4046
return executor.ExecContext(ctx, param)
4147
}
4248

4349
// QueryListContext executes a query and returns a slice of T. Rows are closed after reading.
4450
// (ctx must contain a Manager via ManagerFromContext)
4551
func QueryListContext[T any](ctx context.Context, statement, param any) (result []T, err error) {
46-
manager := ManagerFromContext(ctx)
52+
manager, err := ManagerFromContext(ctx)
53+
if err != nil {
54+
return nil, err
55+
}
4756
rows, err := manager.Object(statement).QueryContext(ctx, param)
4857
if err != nil {
4958
return nil, err
@@ -55,7 +64,10 @@ func QueryListContext[T any](ctx context.Context, statement, param any) (result
5564
// QueryList2Context executes a query and returns a slice of pointers to T. Rows are closed after reading.
5665
// (ctx must contain a Manager via ManagerFromContext)
5766
func QueryList2Context[T any](ctx context.Context, statement, param any) (result []*T, err error) {
58-
manager := ManagerFromContext(ctx)
67+
manager, err := ManagerFromContext(ctx)
68+
if err != nil {
69+
return nil, err
70+
}
5971
rows, err := manager.Object(statement).QueryContext(ctx, param)
6072
if err != nil {
6173
return nil, err
@@ -68,7 +80,10 @@ func QueryList2Context[T any](ctx context.Context, statement, param any) (result
6880
// Rows are automatically closed when iteration completes or stops.
6981
// (ctx must contain a Manager via ManagerFromContext)
7082
func QueryIterContext[T any](ctx context.Context, statement, param any) (sqllib.Iterator[T], error) {
71-
manager := ManagerFromContext(ctx)
83+
manager, err := ManagerFromContext(ctx)
84+
if err != nil {
85+
return nil, err
86+
}
7287
rows, err := manager.Object(statement).QueryContext(ctx, param)
7388
if err != nil {
7489
return nil, err

0 commit comments

Comments
 (0)