mirror of
https://github.com/harness/drone.git
synced 2025-05-03 12:12:22 +08:00
208 lines
3.9 KiB
Go
208 lines
3.9 KiB
Go
// Source: https://github.com/goharbor/harbor
|
|
|
|
// Copyright 2016 Project Harbor Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package errors
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
var (
|
|
// As alias function of `errors.As`.
|
|
As = errors.As
|
|
// Is alias function of `errors.Is`.
|
|
Is = errors.Is
|
|
)
|
|
|
|
// Error ...
|
|
type Error struct {
|
|
Cause error `json:"-"`
|
|
Code string `json:"code"`
|
|
Message string `json:"message"`
|
|
Stack *stack `json:"-"`
|
|
}
|
|
|
|
// Error returns a human readable error, error.Error() will not
|
|
// contains the track information. Needs it? just call error.StackTrace()
|
|
// Code will not be in the error output.
|
|
func (e *Error) Error() string {
|
|
out := e.Message
|
|
if e.Cause != nil {
|
|
out = out + ": " + e.Cause.Error()
|
|
}
|
|
return out
|
|
}
|
|
|
|
// StackTrace ...
|
|
func (e *Error) StackTrace() string {
|
|
return e.Stack.frames().format()
|
|
}
|
|
|
|
// MarshalJSON ...
|
|
func (e *Error) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(
|
|
&struct {
|
|
Code string `json:"code"`
|
|
Message string `json:"message"`
|
|
}{
|
|
Code: e.Code,
|
|
Message: e.Error(),
|
|
},
|
|
)
|
|
}
|
|
|
|
// WithMessage ...
|
|
func (e *Error) WithMessage(format string, v ...interface{}) *Error {
|
|
e.Message = fmt.Sprintf(format, v...)
|
|
return e
|
|
}
|
|
|
|
// WithCode ...
|
|
func (e *Error) WithCode(code string) *Error {
|
|
e.Code = code
|
|
return e
|
|
}
|
|
|
|
// WithCause ...
|
|
func (e *Error) WithCause(err error) *Error {
|
|
e.Cause = err
|
|
return e
|
|
}
|
|
|
|
// Unwrap ...
|
|
func (e *Error) Unwrap() error { return e.Cause }
|
|
|
|
// Errors ...
|
|
type Errors []error
|
|
|
|
var _ error = Errors{}
|
|
|
|
// Error converts slice of error.
|
|
func (errs Errors) Error() string {
|
|
var tmpErrs struct {
|
|
Errors []Error `json:"errors,omitempty"`
|
|
}
|
|
|
|
for _, e := range errs {
|
|
var err *Error
|
|
ok := errors.As(e, &err)
|
|
if !ok {
|
|
err = UnknownError(e)
|
|
}
|
|
if err.Code == "" {
|
|
err.Code = GeneralCode
|
|
}
|
|
|
|
tmpErrs.Errors = append(tmpErrs.Errors, *err)
|
|
}
|
|
|
|
msg, err := json.Marshal(tmpErrs)
|
|
if err != nil {
|
|
log.Error().Stack().Err(err).Msg("")
|
|
return "{}"
|
|
}
|
|
return string(msg)
|
|
}
|
|
|
|
// Len returns the current number of errors.
|
|
func (errs Errors) Len() int {
|
|
return len(errs)
|
|
}
|
|
|
|
// NewErrs ...
|
|
func NewErrs(err error) Errors {
|
|
return Errors{err}
|
|
}
|
|
|
|
// New ...
|
|
func New(in interface{}) *Error {
|
|
var err error
|
|
switch in := in.(type) {
|
|
case error:
|
|
err = in
|
|
default:
|
|
err = fmt.Errorf("%v", in)
|
|
}
|
|
|
|
return &Error{
|
|
Message: err.Error(),
|
|
Stack: newStack(),
|
|
}
|
|
}
|
|
|
|
// Wrap ...
|
|
func Wrap(err error, message string) *Error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
e := &Error{
|
|
Cause: err,
|
|
Message: message,
|
|
Stack: newStack(),
|
|
}
|
|
return e
|
|
}
|
|
|
|
// Wrapf ...
|
|
func Wrapf(err error, format string, args ...interface{}) *Error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
e := &Error{
|
|
Cause: err,
|
|
Message: fmt.Sprintf(format, args...),
|
|
Stack: newStack(),
|
|
}
|
|
return e
|
|
}
|
|
|
|
// Errorf ...
|
|
func Errorf(format string, args ...interface{}) *Error {
|
|
return &Error{
|
|
Message: fmt.Sprintf(format, args...),
|
|
Stack: newStack(),
|
|
}
|
|
}
|
|
|
|
// IsErr checks whether the err chain contains error matches the code.
|
|
func IsErr(err error, code string) bool {
|
|
var e *Error
|
|
if As(err, &e) {
|
|
return e.Code == code
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ErrCode returns code of err.
|
|
func ErrCode(err error) string {
|
|
if err == nil {
|
|
return ""
|
|
}
|
|
|
|
var e *Error
|
|
if ok := As(err, &e); ok && e.Code != "" {
|
|
return e.Code
|
|
} else if ok && e.Cause != nil {
|
|
return ErrCode(e.Cause)
|
|
}
|
|
|
|
return GeneralCode
|
|
}
|