mirror of
https://github.com/hanzoai/traces.git
synced 2026-10-30 18:20:41 +00:00
c855109044
Bumps [github.com/twmb/franz-go/pkg/kadm](https://github.com/twmb/franz-go) from 1.16.0 to 1.17.1. - [Changelog](https://github.com/twmb/franz-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/twmb/franz-go/compare/v1.16.0...v1.17.1) --- updated-dependencies: - dependency-name: github.com/twmb/franz-go/pkg/kadm dependency-version: 1.17.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
135 lines
4.1 KiB
Go
135 lines
4.1 KiB
Go
package kadm
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/twmb/franz-go/pkg/kerr"
|
|
"github.com/twmb/franz-go/pkg/kgo"
|
|
"github.com/twmb/franz-go/pkg/kmsg"
|
|
)
|
|
|
|
// AuthError can be returned from requests for resources that you are not
|
|
// authorized for.
|
|
type AuthError struct {
|
|
Err error // Err is the inner *kerr.Error authorization error.
|
|
}
|
|
|
|
func (a *AuthError) Error() string { return a.Err.Error() }
|
|
func (a *AuthError) Unwrap() error { return a.Err }
|
|
func (a *AuthError) Is(err error) bool { return a.Err == err }
|
|
|
|
func maybeAuthErr(code int16) error {
|
|
switch err := kerr.ErrorForCode(code); err {
|
|
case kerr.ClusterAuthorizationFailed,
|
|
kerr.TopicAuthorizationFailed,
|
|
kerr.GroupAuthorizationFailed,
|
|
kerr.TransactionalIDAuthorizationFailed,
|
|
kerr.DelegationTokenAuthorizationFailed:
|
|
return &AuthError{err}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ShardError is a piece of a request that failed. See ShardErrors for more
|
|
// detail.
|
|
type ShardError struct {
|
|
Req kmsg.Request // Req is a piece of the original request.
|
|
Err error // Err is the error that resulted in this request failing.
|
|
|
|
// Broker, if non-nil, is the broker this request was meant to be
|
|
// issued to. If the NodeID is -1, then this piece of the request
|
|
// failed before being mapped to a broker.
|
|
Broker BrokerDetail
|
|
}
|
|
|
|
// ShardErrors contains each individual error shard of a request.
|
|
//
|
|
// Under the hood, some requests to Kafka need to be mapped to brokers, split,
|
|
// and sent to many brokers. The kgo.Client handles this all internally, but
|
|
// returns the individual pieces that were requested as "shards". Internally,
|
|
// each of these pieces can also fail, and they can all fail uniquely.
|
|
//
|
|
// The kadm package takes one further step and hides the failing pieces into
|
|
// one meta error, the ShardErrors. Methods in this package that can return
|
|
// this meta error are documented; if desired, you can use errors.As to check
|
|
// and unwrap any ShardErrors return.
|
|
//
|
|
// If a request returns ShardErrors, it is possible that some aspects of the
|
|
// request were still successful. You can check ShardErrors.AllFailed as a
|
|
// shortcut for whether any of the response is usable or not.
|
|
type ShardErrors struct {
|
|
Name string // Name is the name of the request these shard errors are for.
|
|
AllFailed bool // AllFailed indicates if the original request was entirely unsuccessful.
|
|
Errs []ShardError // Errs contains all individual shard errors.
|
|
}
|
|
|
|
func shardErrEach(req kmsg.Request, shards []kgo.ResponseShard, fn func(kmsg.Response) error) error {
|
|
return shardErrEachBroker(req, shards, func(_ BrokerDetail, resp kmsg.Response) error {
|
|
return fn(resp)
|
|
})
|
|
}
|
|
|
|
func shardErrEachBroker(req kmsg.Request, shards []kgo.ResponseShard, fn func(BrokerDetail, kmsg.Response) error) error {
|
|
se := ShardErrors{
|
|
Name: kmsg.NameForKey(req.Key()),
|
|
}
|
|
var ae *AuthError
|
|
for _, shard := range shards {
|
|
if shard.Err != nil {
|
|
se.Errs = append(se.Errs, ShardError{
|
|
Req: shard.Req,
|
|
Err: shard.Err,
|
|
Broker: shard.Meta,
|
|
})
|
|
continue
|
|
}
|
|
if err := fn(shard.Meta, shard.Resp); errors.As(err, &ae) {
|
|
return ae
|
|
}
|
|
}
|
|
se.AllFailed = len(shards) == len(se.Errs)
|
|
return se.into()
|
|
}
|
|
|
|
func (se *ShardErrors) into() error {
|
|
if se == nil || len(se.Errs) == 0 {
|
|
return nil
|
|
}
|
|
return se
|
|
}
|
|
|
|
// Merges two shard errors; the input errors should come from the same request.
|
|
func mergeShardErrs(e1, e2 error) error {
|
|
var se1, se2 *ShardErrors
|
|
if !errors.As(e1, &se1) {
|
|
return e2
|
|
}
|
|
if !errors.As(e2, &se2) {
|
|
return e1
|
|
}
|
|
se1.Errs = append(se1.Errs, se2.Errs...)
|
|
se1.AllFailed = se1.AllFailed && se2.AllFailed
|
|
return se1
|
|
}
|
|
|
|
// Error returns an error indicating the name of the request that failed, the
|
|
// number of separate errors, and the first error.
|
|
func (se *ShardErrors) Error() string {
|
|
if len(se.Errs) == 0 {
|
|
return "INVALID: ShardErrors contains no errors!"
|
|
}
|
|
return fmt.Sprintf("request %s has %d separate shard errors, first: %s", se.Name, len(se.Errs), se.Errs[0].Err)
|
|
}
|
|
|
|
// Unwrap returns the underlying errors.
|
|
func (se *ShardErrors) Unwrap() []error {
|
|
unwrapped := make([]error, 0, len(se.Errs))
|
|
|
|
for _, shardErr := range se.Errs {
|
|
unwrapped = append(unwrapped, shardErr.Err)
|
|
}
|
|
|
|
return unwrapped
|
|
}
|