1*1c12ee1eSDan Willemsen// Copyright 2018 The Go Authors. All rights reserved. 2*1c12ee1eSDan Willemsen// Use of this source code is governed by a BSD-style 3*1c12ee1eSDan Willemsen// license that can be found in the LICENSE file. 4*1c12ee1eSDan Willemsen 5*1c12ee1eSDan Willemsen// Package errors implements functions to manipulate errors. 6*1c12ee1eSDan Willemsenpackage errors 7*1c12ee1eSDan Willemsen 8*1c12ee1eSDan Willemsenimport ( 9*1c12ee1eSDan Willemsen "errors" 10*1c12ee1eSDan Willemsen "fmt" 11*1c12ee1eSDan Willemsen 12*1c12ee1eSDan Willemsen "google.golang.org/protobuf/internal/detrand" 13*1c12ee1eSDan Willemsen) 14*1c12ee1eSDan Willemsen 15*1c12ee1eSDan Willemsen// Error is a sentinel matching all errors produced by this package. 16*1c12ee1eSDan Willemsenvar Error = errors.New("protobuf error") 17*1c12ee1eSDan Willemsen 18*1c12ee1eSDan Willemsen// New formats a string according to the format specifier and arguments and 19*1c12ee1eSDan Willemsen// returns an error that has a "proto" prefix. 20*1c12ee1eSDan Willemsenfunc New(f string, x ...interface{}) error { 21*1c12ee1eSDan Willemsen return &prefixError{s: format(f, x...)} 22*1c12ee1eSDan Willemsen} 23*1c12ee1eSDan Willemsen 24*1c12ee1eSDan Willemsentype prefixError struct{ s string } 25*1c12ee1eSDan Willemsen 26*1c12ee1eSDan Willemsenvar prefix = func() string { 27*1c12ee1eSDan Willemsen // Deliberately introduce instability into the error message string to 28*1c12ee1eSDan Willemsen // discourage users from performing error string comparisons. 29*1c12ee1eSDan Willemsen if detrand.Bool() { 30*1c12ee1eSDan Willemsen return "proto: " // use non-breaking spaces (U+00a0) 31*1c12ee1eSDan Willemsen } else { 32*1c12ee1eSDan Willemsen return "proto: " // use regular spaces (U+0020) 33*1c12ee1eSDan Willemsen } 34*1c12ee1eSDan Willemsen}() 35*1c12ee1eSDan Willemsen 36*1c12ee1eSDan Willemsenfunc (e *prefixError) Error() string { 37*1c12ee1eSDan Willemsen return prefix + e.s 38*1c12ee1eSDan Willemsen} 39*1c12ee1eSDan Willemsen 40*1c12ee1eSDan Willemsenfunc (e *prefixError) Unwrap() error { 41*1c12ee1eSDan Willemsen return Error 42*1c12ee1eSDan Willemsen} 43*1c12ee1eSDan Willemsen 44*1c12ee1eSDan Willemsen// Wrap returns an error that has a "proto" prefix, the formatted string described 45*1c12ee1eSDan Willemsen// by the format specifier and arguments, and a suffix of err. The error wraps err. 46*1c12ee1eSDan Willemsenfunc Wrap(err error, f string, x ...interface{}) error { 47*1c12ee1eSDan Willemsen return &wrapError{ 48*1c12ee1eSDan Willemsen s: format(f, x...), 49*1c12ee1eSDan Willemsen err: err, 50*1c12ee1eSDan Willemsen } 51*1c12ee1eSDan Willemsen} 52*1c12ee1eSDan Willemsen 53*1c12ee1eSDan Willemsentype wrapError struct { 54*1c12ee1eSDan Willemsen s string 55*1c12ee1eSDan Willemsen err error 56*1c12ee1eSDan Willemsen} 57*1c12ee1eSDan Willemsen 58*1c12ee1eSDan Willemsenfunc (e *wrapError) Error() string { 59*1c12ee1eSDan Willemsen return format("%v%v: %v", prefix, e.s, e.err) 60*1c12ee1eSDan Willemsen} 61*1c12ee1eSDan Willemsen 62*1c12ee1eSDan Willemsenfunc (e *wrapError) Unwrap() error { 63*1c12ee1eSDan Willemsen return e.err 64*1c12ee1eSDan Willemsen} 65*1c12ee1eSDan Willemsen 66*1c12ee1eSDan Willemsenfunc (e *wrapError) Is(target error) bool { 67*1c12ee1eSDan Willemsen return target == Error 68*1c12ee1eSDan Willemsen} 69*1c12ee1eSDan Willemsen 70*1c12ee1eSDan Willemsenfunc format(f string, x ...interface{}) string { 71*1c12ee1eSDan Willemsen // avoid "proto: " prefix when chaining 72*1c12ee1eSDan Willemsen for i := 0; i < len(x); i++ { 73*1c12ee1eSDan Willemsen switch e := x[i].(type) { 74*1c12ee1eSDan Willemsen case *prefixError: 75*1c12ee1eSDan Willemsen x[i] = e.s 76*1c12ee1eSDan Willemsen case *wrapError: 77*1c12ee1eSDan Willemsen x[i] = format("%v: %v", e.s, e.err) 78*1c12ee1eSDan Willemsen } 79*1c12ee1eSDan Willemsen } 80*1c12ee1eSDan Willemsen return fmt.Sprintf(f, x...) 81*1c12ee1eSDan Willemsen} 82*1c12ee1eSDan Willemsen 83*1c12ee1eSDan Willemsenfunc InvalidUTF8(name string) error { 84*1c12ee1eSDan Willemsen return New("field %v contains invalid UTF-8", name) 85*1c12ee1eSDan Willemsen} 86*1c12ee1eSDan Willemsen 87*1c12ee1eSDan Willemsenfunc RequiredNotSet(name string) error { 88*1c12ee1eSDan Willemsen return New("required field %v not set", name) 89*1c12ee1eSDan Willemsen} 90