How to catch ErrAborted in dgraph go client


(John Goodall) #1

Using the golang client, dgo, I am trying to catch ErrAborted errors and retry, as per instructions in the README: https://github.com/dgraph-io/dgo#commit-a-transaction

In my application logs I am seeing a few errors like this: rpc error: code = Aborted desc = Transaction has been aborted. Please retry. However, my retry code never gets called, leading me to think that y.ErrAborted check is not working the way I expect from the docs. Is it returning the wrong error?

My code:

	for i := 0; i < maxRetries; i++ {
		_, err := dg.NewTxn().Mutate(ctx, mu)
		if err != nil {
			if err == y.ErrAborted {
				// This never gets called
				sleep := time.Duration(time.Duration(rand.Intn(10)) * time.Second)
				logger.Warn("mutation aborted, retrying...", zap.Error(err), zap.Duration("retry-in", sleep), zap.Int("attempt", i))
				time.Sleep(sleep)
			} else {
				logger.Error("error mutating graph", zap.Error(err), zap.Int("attempt", i))
				break
			}
		} else {
			// mutation was successful.
			break
		}

Thanks.


(Daniel Mai) #2

Looks alright to me. The issue might be clearer with a full code example. For instance, it’s not clear if the mutations you’re running are being committed by .Commit(ctx) or by setting CommitNow: true in the mutation.


(John Goodall) #3

I am setting CommitNow: true as part of the mutation, but I thought those were equivalent. The problem is that the if statement never evaluated to true.


(Daniel Mai) #4

They are equivalent.

Can you confirm that the err is ever about aborted transactions? The snippet you shared is the proper way to catch them.


(John Goodall) #5

The mutation is a bunch of nQuads, like this:

mu := &dgoapi.Mutation{
	Set:       nQuads,
	CommitNow: true,
}

It seems to me like the error is about aborted transactions, but the if err == y.ErrAborted { ... } statement never fires. The error I get in dgo is: rpc error: code = Aborted desc = Transaction has been aborted. Please retry. Since the return code from Mutate() is Aborted, I think it is about aborted transactions.


(Gus) #6

y.ErrAborted is emitted by txn.Commit() not by txn.Mutate(). We’ll need to change Mutate() to do that, which IMO seems reasonable. In the meantime I’d recommend to use Commit() to get the response that you need. If you can notice in the example code, it’s using Commit().


(Manish R Jain) #7

We can probably make a change in Mutate so it catches this error correctly.


(Gus) #8

Issue with PR, feel free to comment - https://github.com/dgraph-io/dgo/issues/46


(John Goodall) #9

Ok, so I understand, there are two ways to perform a mutation:

  1. Use Mutate:
mu := &api.Mutation{
	Set:       nQuads,
	CommitNow: true,
}
_, err := dg.NewTxn().Mutate(ctx, mu)
  1. Use Commit
mu := &api.Mutation{
	Set:       nQuads,
}
_, err := dg.NewTxn().Mutate(ctx, mu).Commit()

Is that correct? So in the short term I can just use the second to catch the ErrAborted ?

Thanks.


(Manish R Jain) #10

Yes, the second one catches the error correctly. Note that you can also do string index lookup to check for commit abort in the first case right now as well. Saves you a roundtrip for the extra commit call.


(John Goodall) #11

Something like this?

if strings.Contains(err.Error(), "Transaction has been aborted") { ... }


(Manish R Jain) #12

Yeah. You can look at the Go client library to confirm.