Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: grpc/grpcutil/errors.go

Issue 2951393002: [errors] de-specialize Transient in favor of Tags. (Closed)
Patch Set: more refactor Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package grpcutil 5 package grpcutil
6 6
7 import ( 7 import (
8 "github.com/luci/luci-go/common/errors"
9
10 "google.golang.org/grpc" 8 "google.golang.org/grpc"
11 "google.golang.org/grpc/codes" 9 "google.golang.org/grpc/codes"
10
11 "github.com/luci/luci-go/common/errors"
12 "github.com/luci/luci-go/common/retry/transient"
12 ) 13 )
13 14
14 var ( 15 var (
15 // Errf falls through to grpc.Errorf, with the notable exception that it isn't 16 // Errf falls through to grpc.Errorf, with the notable exception that it isn't
16 // named "Errorf" and, consequently, won't trigger "go vet" misuse error s. 17 // named "Errorf" and, consequently, won't trigger "go vet" misuse error s.
17 Errf = grpc.Errorf 18 Errf = grpc.Errorf
18 19
19 // OK is an empty grpc.OK status error. 20 // OK is an empty grpc.OK status error.
20 OK = Errf(codes.OK, "") 21 OK = Errf(codes.OK, "")
21 22
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 // If the supplied error is nil, nil will be returned. 75 // If the supplied error is nil, nil will be returned.
75 // 76 //
76 // Note that non-gRPC errors will have code grpc.Unknown, which is considered 77 // Note that non-gRPC errors will have code grpc.Unknown, which is considered
77 // transient, and be wrapped. This function should only be used on gRPC errors. 78 // transient, and be wrapped. This function should only be used on gRPC errors.
78 func WrapIfTransient(err error) error { 79 func WrapIfTransient(err error) error {
79 if err == nil { 80 if err == nil {
80 return nil 81 return nil
81 } 82 }
82 83
83 if IsTransientCode(Code(err)) { 84 if IsTransientCode(Code(err)) {
84 » » err = errors.WrapTransient(err) 85 » » err = transient.Tag.Apply(err)
85 } 86 }
86 return err 87 return err
87 } 88 }
88 89
89 const grpcCodeKey = "__grpcutil.Code" 90 type grpcCodeTag struct{ Key errors.TagKey }
dnj 2017/06/27 03:57:03 QQ: why is "Key" named here (and elsewhere)?
iannucci 2017/06/27 18:14:27 Because TagKey is a pointer type, it can't be embe
91
92 func (g grpcCodeTag) With(code codes.Code) errors.TagValue { return errors.MkTag Value(g.Key, code) }
93 func (g grpcCodeTag) In(err error) (v codes.Code, ok bool) {
94 » d, ok := errors.TagValueIn(g.Key, err)
95 » if ok {
96 » » v = d.(codes.Code)
97 » }
98 » return
99 }
100
101 // Tag may be used to associate a gRPC status code with this error.
102 //
103 // The tag value MUST be a "google.golang.org/grpc/codes".Code.
104 var Tag = grpcCodeTag{errors.NewTagKey("gRPC Code")}
90 105
91 // Code returns the gRPC code for a given error. 106 // Code returns the gRPC code for a given error.
92 // 107 //
93 // In addition to the functionality of grpc.Code, this will unwrap any wrapped 108 // In addition to the functionality of grpc.Code, this will unwrap any wrapped
94 // errors before asking for its code. 109 // errors before asking for its code.
95 func Code(err error) codes.Code { 110 func Code(err error) codes.Code {
96 » if code := errors.ExtractData(err, grpcCodeKey); code != nil { 111 » if code, ok := Tag.In(err); ok {
97 » » return code.(codes.Code) 112 » » return code
98 } 113 }
99 return grpc.Code(errors.Unwrap(err)) 114 return grpc.Code(errors.Unwrap(err))
100 } 115 }
101 116
102 // Annotate begins annotating the error, and adds the given gRPC code.
103 // This code may be extracted with the Code function in this package.
104 func Annotate(err error, code codes.Code) *errors.Annotator {
105 return errors.Annotate(err).D(grpcCodeKey, code)
106 }
107
108 // ToGRPCErr is a shorthand for Errf(Code(err), "%s", err) 117 // ToGRPCErr is a shorthand for Errf(Code(err), "%s", err)
109 func ToGRPCErr(err error) error { 118 func ToGRPCErr(err error) error {
110 return Errf(Code(err), "%s", err) 119 return Errf(Code(err), "%s", err)
111 } 120 }
112 121
113 // IsTransientCode returns true if a given gRPC code is associated with a 122 // IsTransientCode returns true if a given gRPC code is associated with a
114 // transient gRPC error type. 123 // transient gRPC error type.
115 func IsTransientCode(code codes.Code) bool { 124 func IsTransientCode(code codes.Code) bool {
116 switch code { 125 switch code {
117 case codes.Internal, codes.Unknown, codes.Unavailable: 126 case codes.Internal, codes.Unknown, codes.Unavailable:
118 return true 127 return true
119 128
120 default: 129 default:
121 return false 130 return false
122 } 131 }
123 } 132 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698