Skip to content

Commit e12e2d7

Browse files
committed
bigtable: fix error variable shadowing bugs when tracing by named return
Previously in bigtable.(*Table).Apply we started a span and on defer ended with an error that had been previously declared. However, in the body of that function, while in the m.cond == nil scope, we shadowed the original error with: err := gax.Invoke which means that regardless of the result of that newly declared/shadowed "err" error, we would always end the span with a success. An illustration of this problem is: https://play.golang.org/p/1iesjtxGI-e Using a named return parameter ensures that we always capture the finally written error value, regardless of shadowing or a new name at return time. While here I examined a few usages of func <func_name>(ctx context.Context) error { var err error ctx = trace.Startspan(ctx, <span_name>) defer func() { trace.EndSpan(ctx, err) }() and changed them to: func <func_name>(ctx context.Context) (err error) { ctx = trace.Startspan(ctx, <span_name>) defer func() { trace.EndSpan(ctx, err) }() which will prevent the reported problem from creeping back in. Change-Id: I63dd12486844b2fae9d946f895e5c85f80a3a3e1 Reviewed-on: https://code-review.googlesource.com/c/gocloud/+/39651 Reviewed-by: kokoro <[email protected]> Reviewed-by: Jean de Klerk <[email protected]>
1 parent 1de5fdf commit e12e2d7

File tree

1 file changed

+9
-13
lines changed

1 file changed

+9
-13
lines changed

bigtable/bigtable.go

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,12 @@ func (c *Client) Open(table string) *Table {
143143
//
144144
// By default, the yielded rows will contain all values in all cells.
145145
// Use RowFilter to limit the cells returned.
146-
func (t *Table) ReadRows(ctx context.Context, arg RowSet, f func(Row) bool, opts ...ReadOption) error {
146+
func (t *Table) ReadRows(ctx context.Context, arg RowSet, f func(Row) bool, opts ...ReadOption) (err error) {
147147
ctx = mergeOutgoingMetadata(ctx, t.md)
148-
149-
var prevRowKey string
150-
var err error
151148
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigtable.ReadRows")
152149
defer func() { trace.EndSpan(ctx, err) }()
150+
151+
var prevRowKey string
153152
attrMap := make(map[string]interface{})
154153
err = gax.Invoke(ctx, func(ctx context.Context) error {
155154
if !arg.valid() {
@@ -469,15 +468,14 @@ const maxMutations = 100000
469468

470469
// Apply mutates a row atomically. A mutation must contain at least one
471470
// operation and at most 100000 operations.
472-
func (t *Table) Apply(ctx context.Context, row string, m *Mutation, opts ...ApplyOption) error {
471+
func (t *Table) Apply(ctx context.Context, row string, m *Mutation, opts ...ApplyOption) (err error) {
473472
ctx = mergeOutgoingMetadata(ctx, t.md)
474473
after := func(res proto.Message) {
475474
for _, o := range opts {
476475
o.after(res)
477476
}
478477
}
479478

480-
var err error
481479
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigtable/Apply")
482480
defer func() { trace.EndSpan(ctx, err) }()
483481
var callOptions []gax.CallOption
@@ -642,8 +640,11 @@ type entryErr struct {
642640
// will correspond to the relevant rowKeys/muts arguments.
643641
//
644642
// Conditional mutations cannot be applied in bulk and providing one will result in an error.
645-
func (t *Table) ApplyBulk(ctx context.Context, rowKeys []string, muts []*Mutation, opts ...ApplyOption) ([]error, error) {
643+
func (t *Table) ApplyBulk(ctx context.Context, rowKeys []string, muts []*Mutation, opts ...ApplyOption) (errs []error, err error) {
646644
ctx = mergeOutgoingMetadata(ctx, t.md)
645+
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigtable/ApplyBulk")
646+
defer func() { trace.EndSpan(ctx, err) }()
647+
647648
if len(rowKeys) != len(muts) {
648649
return nil, fmt.Errorf("mismatched rowKeys and mutation array lengths: %d, %d", len(rowKeys), len(muts))
649650
}
@@ -657,10 +658,6 @@ func (t *Table) ApplyBulk(ctx context.Context, rowKeys []string, muts []*Mutatio
657658
origEntries[i] = &entryErr{Entry: &btpb.MutateRowsRequest_Entry{RowKey: []byte(key), Mutations: mut.ops}}
658659
}
659660

660-
var err error
661-
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigtable/ApplyBulk")
662-
defer func() { trace.EndSpan(ctx, err) }()
663-
664661
for _, group := range groupEntries(origEntries, maxMutations) {
665662
attrMap := make(map[string]interface{})
666663
err = gax.Invoke(ctx, func(ctx context.Context) error {
@@ -684,9 +681,8 @@ func (t *Table) ApplyBulk(ctx context.Context, rowKeys []string, muts []*Mutatio
684681
}
685682
}
686683

687-
// Accumulate all of the errors into an array to return, interspersed with nils for successful
684+
// All the errors are accumulated into an array and returned, interspersed with nils for successful
688685
// entries. The absence of any errors means we should return nil.
689-
var errs []error
690686
var foundErr bool
691687
for _, entry := range origEntries {
692688
if entry.Err != nil {

0 commit comments

Comments
 (0)