github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/errorutil/unimplemented/unimplemented.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package unimplemented 12 13 import ( 14 "fmt" 15 16 "github.com/cockroachdb/errors" 17 ) 18 19 // This file re-implements the unimplemented primitives from the 20 // original pgerror package, using the primitives from the errors 21 // library instead. 22 23 // New constructs an unimplemented feature error. 24 func New(feature, msg string) error { 25 return unimplementedInternal(1 /*depth*/, 0 /*issue*/, feature /*detail*/, false /*format*/, msg) 26 } 27 28 // Newf constructs an unimplemented feature error. 29 // The message is formatted. 30 func Newf(feature, format string, args ...interface{}) error { 31 return NewWithDepthf(1, feature, format, args...) 32 } 33 34 // NewWithDepthf constructs an implemented feature error, 35 // tracking the context at the specified depth. 36 func NewWithDepthf(depth int, feature, format string, args ...interface{}) error { 37 return unimplementedInternal(depth+1 /*depth*/, 0 /*issue*/, feature /*detail*/, true /*format*/, format, args...) 38 } 39 40 // NewWithIssue constructs an error with the given message 41 // and a link to the passed issue. Recorded as "#<issue>" in tracking. 42 func NewWithIssue(issue int, msg string) error { 43 return unimplementedInternal(1 /*depth*/, issue, "" /*detail*/, false /*format*/, msg) 44 } 45 46 // NewWithIssuef constructs an error with the formatted message 47 // and a link to the passed issue. Recorded as "#<issue>" in tracking. 48 func NewWithIssuef(issue int, format string, args ...interface{}) error { 49 return unimplementedInternal(1 /*depth*/, issue, "" /*detail*/, true /*format*/, format, args...) 50 } 51 52 // NewWithIssueDetail constructs an error with the given message 53 // and a link to the passed issue. Recorded as "#<issue>.detail" in tracking. 54 // This is useful when we need an extra axis of information to drill down into. 55 func NewWithIssueDetail(issue int, detail, msg string) error { 56 return unimplementedInternal(1 /*depth*/, issue, detail, false /*format*/, msg) 57 } 58 59 // NewWithIssueDetailf is like NewWithIssueDetail but the message is formatted. 60 func NewWithIssueDetailf(issue int, detail, format string, args ...interface{}) error { 61 return unimplementedInternal(1 /*depth*/, issue, detail, true /*format*/, format, args...) 62 } 63 64 func unimplementedInternal( 65 depth, issue int, detail string, format bool, msg string, args ...interface{}, 66 ) error { 67 // Create the issue link. 68 link := errors.IssueLink{Detail: detail} 69 if issue > 0 { 70 link.IssueURL = MakeURL(issue) 71 } 72 73 // Instantiate the base error. 74 var err error 75 if format { 76 err = errors.UnimplementedErrorf(link, "unimplemented: "+msg, args...) 77 err = errors.WithSafeDetails(err, msg, args...) 78 } else { 79 err = errors.UnimplementedError(link, "unimplemented: "+msg) 80 } 81 // Decorate with a stack trace. 82 err = errors.WithStackDepth(err, 1+depth) 83 84 if issue > 0 { 85 // There is an issue number. Decorate with a telemetry annotation. 86 var key string 87 if detail == "" { 88 key = fmt.Sprintf("#%d", issue) 89 } else { 90 key = fmt.Sprintf("#%d.%s", issue, detail) 91 } 92 err = errors.WithTelemetry(err, key) 93 } else if detail != "" { 94 // No issue but a detail string. It's an indication to also 95 // perform telemetry. 96 err = errors.WithTelemetry(err, detail) 97 } 98 return err 99 } 100 101 // MakeURL produces a URL to a CockroachDB issue. 102 func MakeURL(issue int) string { 103 return fmt.Sprintf("https://github.com/cockroachdb/cockroach/issues/%d", issue) 104 }