rclone/vendor/storj.io/common/rpc/rpcstatus/status.go
Caleb Case e7bd392a69 backend/tardigrade: Upgrade to uplink v1.0.6
This fixes an important bug with listing that affects users with more
than 500 objects in a listing operation.
2020-05-29 18:00:08 +01:00

106 lines
2.1 KiB
Go

// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
// Package rpcstatus contains status code definitions for rpc.
package rpcstatus
import (
"context"
"fmt"
"github.com/zeebo/errs"
"storj.io/drpc/drpcerr"
)
// StatusCode is an enumeration of rpc status codes.
type StatusCode uint64
// These constants are all the rpc error codes. It is important that
// their numerical values do not change.
const (
Unknown StatusCode = iota
OK
Canceled
InvalidArgument
DeadlineExceeded
NotFound
AlreadyExists
PermissionDenied
ResourceExhausted
FailedPrecondition
Aborted
OutOfRange
Unimplemented
Internal
Unavailable
DataLoss
Unauthenticated
)
// Code returns the status code associated with the error.
func Code(err error) StatusCode {
// special case: if the error is context canceled or deadline exceeded, the code
// must be those. additionally, grpc returns OK for a nil error, so we will, too.
switch err {
case nil:
return OK
case context.Canceled:
return Canceled
case context.DeadlineExceeded:
return DeadlineExceeded
default:
if code := StatusCode(drpcerr.Code(err)); code != Unknown {
return code
}
return Unknown
}
}
// Wrap wraps the error with the provided status code.
func Wrap(code StatusCode, err error) error {
if err == nil {
return nil
}
ce := &codeErr{
code: code,
}
if ee, ok := err.(errsError); ok {
ce.errsError = ee
} else {
ce.errsError = errs.Wrap(err).(errsError)
}
return ce
}
// Error wraps the message with a status code into an error.
func Error(code StatusCode, msg string) error {
return Wrap(code, errs.New("%s", msg))
}
// Errorf : Error :: fmt.Sprintf : fmt.Sprint.
func Errorf(code StatusCode, format string, a ...interface{}) error {
return Wrap(code, errs.New(format, a...))
}
type errsError interface {
error
fmt.Formatter
Name() (string, bool)
}
// codeErr implements error that can work both in grpc and drpc.
type codeErr struct {
errsError
code StatusCode
}
func (c *codeErr) Unwrap() error { return c.errsError }
func (c *codeErr) Cause() error { return c.errsError }
func (c *codeErr) Code() uint64 { return uint64(c.code) }