// Copyright (c) 2017 Uber Technologies, Inc.1//2// Permission is hereby granted, free of charge, to any person obtaining a copy3// of this software and associated documentation files (the "Software"), to deal4// in the Software without restriction, including without limitation the rights5// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell6// copies of the Software, and to permit persons to whom the Software is7// furnished to do so, subject to the following conditions:8//9// The above copyright notice and this permission notice shall be included in10// all copies or substantial portions of the Software.11//12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR13// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,14// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE15// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER16// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,17// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN18// THE SOFTWARE.1920package zap2122import (23"go.uber.org/zap/internal/pool"24"go.uber.org/zap/zapcore"25)2627var _errArrayElemPool = pool.New(func() *errArrayElem {28return &errArrayElem{}29})3031// Error is shorthand for the common idiom NamedError("error", err).32func Error(err error) Field {33return NamedError("error", err)34}3536// NamedError constructs a field that lazily stores err.Error() under the37// provided key. Errors which also implement fmt.Formatter (like those produced38// by github.com/pkg/errors) will also have their verbose representation stored39// under key+"Verbose". If passed a nil error, the field is a no-op.40//41// For the common case in which the key is simply "error", the Error function42// is shorter and less repetitive.43func NamedError(key string, err error) Field {44if err == nil {45return Skip()46}47return Field{Key: key, Type: zapcore.ErrorType, Interface: err}48}4950type errArray []error5152func (errs errArray) MarshalLogArray(arr zapcore.ArrayEncoder) error {53for i := range errs {54if errs[i] == nil {55continue56}57// To represent each error as an object with an "error" attribute and58// potentially an "errorVerbose" attribute, we need to wrap it in a59// type that implements LogObjectMarshaler. To prevent this from60// allocating, pool the wrapper type.61elem := _errArrayElemPool.Get()62elem.error = errs[i]63err := arr.AppendObject(elem)64elem.error = nil65_errArrayElemPool.Put(elem)66if err != nil {67return err68}69}70return nil71}7273type errArrayElem struct {74error75}7677func (e *errArrayElem) MarshalLogObject(enc zapcore.ObjectEncoder) error {78// Re-use the error field's logic, which supports non-standard error types.79Error(e.error).AddTo(enc)80return nil81}828384