@@ -1826,7 +1826,7 @@ func (ds *DistSender) sendPartialBatch(
18261826 // deduceRetryEarlyExitError() call below the loop is inhibited.
18271827 pErr = kvpb .NewError (err )
18281828 switch {
1829- case errors . HasType (err , sendError {} ):
1829+ case IsSendError (err ):
18301830 // We've tried all the replicas without success. Either they're all
18311831 // down, or we're using an out-of-date range descriptor. Evict from the
18321832 // cache and try again with an updated descriptor. Re-sending the
@@ -2080,7 +2080,7 @@ func noMoreReplicasErr(ambiguousErr, lastAttemptErr error) error {
20802080 // one to return; we may want to remember the "best" error we've seen (for
20812081 // example, a NotLeaseHolderError conveys more information than a
20822082 // RangeNotFound).
2083- return newSendError (fmt . Sprintf ( "sending to all replicas failed; last error: %s" , lastAttemptErr ))
2083+ return newSendError (errors . Wrap ( lastAttemptErr , "sending to all replicas failed; last error" ))
20842084}
20852085
20862086// defaultSendClosedTimestampPolicy is used when the closed timestamp policy
@@ -2463,7 +2463,7 @@ func (ds *DistSender) sendToReplicas(
24632463 log .VEventf (
24642464 ctx , 2 , "transport incompatible with updated routing; bailing early" ,
24652465 )
2466- return nil , newSendError (fmt . Sprintf ( "leaseholder not found in transport; last error: %s" , tErr . Error () ))
2466+ return nil , newSendError (errors . Wrap ( tErr , "leaseholder not found in transport; last error" ))
24672467 }
24682468 }
24692469 }
@@ -2705,28 +2705,32 @@ func skipStaleReplicas(
27052705// TODO(andrei): clean up this stuff and tighten the meaning of the different
27062706// errors.
27072707type sendError struct {
2708- message string
2708+ cause error
27092709}
27102710
2711- // newSendError creates a sendError.
2712- func newSendError (msg string ) error {
2713- return sendError {message : msg }
2711+ // newSendError creates a sendError that wraps the given error .
2712+ func newSendError (err error ) error {
2713+ return & sendError {cause : err }
27142714}
27152715
27162716// TestNewSendError creates a new sendError for the purpose of unit tests
27172717func TestNewSendError (msg string ) error {
2718- return newSendError (msg )
2718+ return newSendError (errors . NewWithDepthf ( 1 , "%s" , msg ) )
27192719}
27202720
2721- // SendErrorString is the prefix for all sendErrors, exported in order to
2722- // perform cross-node error-checks.
2723- const SendErrorString = "failed to send RPC"
2724-
2725- func (s sendError ) Error () string {
2726- return SendErrorString + ": " + s .message
2721+ // Error implements error.
2722+ func (s * sendError ) Error () string {
2723+ return fmt .Sprintf ("failed to send RPC: %s" , s .cause )
27272724}
27282725
2726+ // Cause implements errors.Causer.
2727+ // NB: this is an obsolete method, use Unwrap() instead.
2728+ func (s * sendError ) Cause () error { return s .cause }
2729+
2730+ // Unwrap implements errors.Wrapper.
2731+ func (s * sendError ) Unwrap () error { return s .cause }
2732+
27292733// IsSendError returns true if err is a sendError.
27302734func IsSendError (err error ) bool {
2731- return errors .HasType (err , sendError {})
2735+ return errors .HasType (err , & sendError {})
27322736}
0 commit comments