Skip to content

Instantly share code, notes, and snippets.

@smyrman
Last active July 14, 2019 17:01
Show Gist options
  • Save smyrman/42d4aa4ea34651b53bd70f17474086b6 to your computer and use it in GitHub Desktop.
Save smyrman/42d4aa4ea34651b53bd70f17474086b6 to your computer and use it in GitHub Desktop.
Go 1.13 errors
func EnsureFoo(client jsonrpc.Client, maxRetries int) error {
var backof time.Duration
for retry:= 0; retry < maxRetries; retry++ {
time.Sleep(backof)
_, err := client.Call("foobar.Foo", json.RawMessage(`["bar"]`))
switch errT := err.(type) {
case nil:
return nil
case jsonrpc.Error:
switch {
case err.Code >= -32700 && err.Code <= -32600:
// There is something wrong with out request, abort.
return fmt.Errorf("permanent failure: %s", err)
default:
log.Printf("RPC call failed (attempt %d/%d): %s", 1+retry, maxRetries, err)
backoff += time.Second
}
case jsonrpc.HTTPStatusError:
switch {
case err.Code >= 300 && err.Code < 500:
return fmt.Errorf("failed after %d retries: %s", maxRetries, err)
cdefault:
return fmt.Errorf("aborted: %s", err)
default:
backoff += time.Second
}
default:
return fmt.Errorf("aborted: %s", err)
}
}
return errors.New("all retries failed", maxRetries)
}
var (
ErrPersistent = errT{msg: "persistent failute"}
ErrAllRetriesFailed = errT{msg: "all retries failed"}
)
func EnsureFoo(client jsonrpc.Client, maxRetries int) error {
var backof time.Duration
for retry:= 0; retry < maxRetries; retry++ {
time.Sleep(backof)
_, err := client.Call("foobar.Foo", json.RawMessage(`["bar"]`))
switch {
case err == nil:
return nil
case errors.Is(err, jsonrpc.ErrRangeHTTPPersistent):
falltrough
case errors.Is(err, jsonrpc.ErrRangeRPCRequest):
return ErrPersistent.wrap(err)
default:
log.Printf("RPC call failed (attempt %d/%d): %s", 1+retry, maxRetries, err)
backoff += time.Second
}
}
return ErrAllRetriesFailed
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment