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

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

Issue 2951393002: [errors] de-specialize Transient in favor of Tags. (Closed)
Patch Set: copyright Created 3 years, 6 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"
12 ) 13 )
13 14
15 // Errf falls through to grpc.Errorf, but will tag the resulting error with
16 // retry.Tag if it's transient.
17 //
18 // This is named `Errf` so that it won't trigger "go vet" misuse errors.
19 func Errf(code codes.Code, fmt string, a ...interface{}) error {
20 ret := grpc.Errorf(code, fmt, a...)
21 if IsTransientCode(code) {
22 ret = retry.Tag.Apply(ret)
dnj 2017/06/24 14:53:55 This is concerning to me WRT current behavior. I l
iannucci 2017/06/24 20:16:10 I'll undo this for now then
23 }
24 return ret
25 }
26
14 var ( 27 var (
15 // 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 Errf = grpc.Errorf
18
19 // OK is an empty grpc.OK status error. 28 // OK is an empty grpc.OK status error.
20 OK = Errf(codes.OK, "") 29 OK = Errf(codes.OK, "")
21 30
22 // Canceled is an empty grpc.Canceled error. 31 // Canceled is an empty grpc.Canceled error.
23 Canceled = Errf(codes.Canceled, "") 32 Canceled = Errf(codes.Canceled, "")
24 33
25 // Unknown is an empty grpc.Unknown error. 34 // Unknown is an empty grpc.Unknown error.
26 Unknown = Errf(codes.Unknown, "") 35 Unknown = Errf(codes.Unknown, "")
27 36
28 // InvalidArgument is an empty grpc.InvalidArgument error. 37 // InvalidArgument is an empty grpc.InvalidArgument error.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 // If the supplied error is nil, nil will be returned. 83 // If the supplied error is nil, nil will be returned.
75 // 84 //
76 // Note that non-gRPC errors will have code grpc.Unknown, which is considered 85 // 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. 86 // transient, and be wrapped. This function should only be used on gRPC errors.
78 func WrapIfTransient(err error) error { 87 func WrapIfTransient(err error) error {
79 if err == nil { 88 if err == nil {
80 return nil 89 return nil
81 } 90 }
82 91
83 if IsTransientCode(Code(err)) { 92 if IsTransientCode(Code(err)) {
84 » » err = errors.WrapTransient(err) 93 » » err = retry.Tag.Apply(err)
85 } 94 }
86 return err 95 return err
87 } 96 }
88 97
89 const grpcCodeKey = "__grpcutil.Code" 98 // Tag may be used to associate a gRPC status code with this error.
99 //
100 // The tag value MUST be a "google.golang.org/grpc/codes".Code.
101 var Tag = errors.NewTagger("gRPC Code", func(v interface{}) {
102 » _ = v.(codes.Code)
103 })
90 104
91 // Code returns the gRPC code for a given error. 105 // Code returns the gRPC code for a given error.
92 // 106 //
93 // In addition to the functionality of grpc.Code, this will unwrap any wrapped 107 // In addition to the functionality of grpc.Code, this will unwrap any wrapped
94 // errors before asking for its code. 108 // errors before asking for its code.
95 func Code(err error) codes.Code { 109 func Code(err error) codes.Code {
96 » if code := errors.ExtractData(err, grpcCodeKey); code != nil { 110 » if code, ok := Tag.ValueIn(err); ok {
97 return code.(codes.Code) 111 return code.(codes.Code)
98 } 112 }
99 return grpc.Code(errors.Unwrap(err)) 113 return grpc.Code(errors.Unwrap(err))
100 } 114 }
101 115
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) 116 // ToGRPCErr is a shorthand for Errf(Code(err), "%s", err)
109 func ToGRPCErr(err error) error { 117 func ToGRPCErr(err error) error {
110 return Errf(Code(err), "%s", err) 118 return Errf(Code(err), "%s", err)
111 } 119 }
112 120
113 // IsTransientCode returns true if a given gRPC code is associated with a 121 // IsTransientCode returns true if a given gRPC code is associated with a
114 // transient gRPC error type. 122 // transient gRPC error type.
115 func IsTransientCode(code codes.Code) bool { 123 func IsTransientCode(code codes.Code) bool {
116 switch code { 124 switch code {
117 case codes.Internal, codes.Unknown, codes.Unavailable: 125 case codes.Internal, codes.Unknown, codes.Unavailable:
118 return true 126 return true
119 127
120 default: 128 default:
121 return false 129 return false
122 } 130 }
123 } 131 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698