Files
Xray-core/common/errors/errors.go
T

176 lines
3.7 KiB
Go
Raw Normal View History

2020-11-25 19:01:53 +08:00
// Package errors is a drop-in replacement for Golang lib 'errors'.
2020-12-04 09:36:16 +08:00
package errors // import "github.com/xtls/xray-core/common/errors"
2020-11-25 19:01:53 +08:00
import (
2024-06-29 14:32:57 -04:00
"context"
"runtime"
2020-11-25 19:01:53 +08:00
"strings"
2024-06-29 14:32:57 -04:00
c "github.com/xtls/xray-core/common/ctx"
2020-12-04 09:36:16 +08:00
"github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/serial"
2020-11-25 19:01:53 +08:00
)
2020-12-04 09:36:16 +08:00
const trim = len("github.com/xtls/xray-core/")
2020-11-25 19:01:53 +08:00
type hasInnerError interface {
2022-06-01 11:03:06 +08:00
// Unwrap returns the underlying error of this one.
Unwrap() error
2020-11-25 19:01:53 +08:00
}
// Error is an error object with underlying error.
type Error struct {
2026-09-20 17:00:49 +08:00
prefix []interface{}
message []interface{}
caller string
inner error
2020-11-25 19:01:53 +08:00
}
// Error implements error.Error().
func (err *Error) Error() string {
builder := strings.Builder{}
for _, prefix := range err.prefix {
builder.WriteByte('[')
builder.WriteString(serial.ToString(prefix))
builder.WriteString("] ")
}
2024-06-29 14:32:57 -04:00
if len(err.caller) > 0 {
builder.WriteString(err.caller)
2020-11-25 19:01:53 +08:00
builder.WriteString(": ")
}
msg := serial.Concat(err.message...)
builder.WriteString(msg)
if err.inner != nil {
builder.WriteString(" > ")
builder.WriteString(err.inner.Error())
}
return builder.String()
}
2022-06-01 11:03:06 +08:00
// Unwrap implements hasInnerError.Unwrap()
func (err *Error) Unwrap() error {
2020-11-25 19:01:53 +08:00
if err.inner == nil {
return nil
}
return err.inner
}
func (err *Error) Base(e error) *Error {
err.inner = e
return err
}
// String returns the string representation of this error.
func (err *Error) String() string {
return err.Error()
}
type ExportOptionHolder struct {
SessionID uint32
}
type ExportOption func(*ExportOptionHolder)
// New returns a new error object with message formed from given arguments.
func New(msg ...interface{}) *Error {
2024-06-29 14:32:57 -04:00
pc, _, _, _ := runtime.Caller(1)
details := runtime.FuncForPC(pc).Name()
if len(details) >= trim {
details = details[trim:]
}
i := strings.Index(details, ".")
if i > 0 {
details = details[:i]
}
2020-11-25 19:01:53 +08:00
return &Error{
2026-09-20 17:00:49 +08:00
message: msg,
caller: details,
2024-06-29 14:32:57 -04:00
}
}
func LogDebug(ctx context.Context, msg ...interface{}) {
doLog(ctx, nil, log.Severity_Debug, msg...)
}
func LogDebugInner(ctx context.Context, inner error, msg ...interface{}) {
doLog(ctx, inner, log.Severity_Debug, msg...)
}
func LogInfo(ctx context.Context, msg ...interface{}) {
doLog(ctx, nil, log.Severity_Info, msg...)
}
func LogInfoInner(ctx context.Context, inner error, msg ...interface{}) {
2024-07-15 15:34:04 +03:30
doLog(ctx, inner, log.Severity_Info, msg...)
2024-06-29 14:32:57 -04:00
}
func LogWarning(ctx context.Context, msg ...interface{}) {
doLog(ctx, nil, log.Severity_Warning, msg...)
}
func LogWarningInner(ctx context.Context, inner error, msg ...interface{}) {
2024-07-15 15:34:04 +03:30
doLog(ctx, inner, log.Severity_Warning, msg...)
2024-06-29 14:32:57 -04:00
}
func LogError(ctx context.Context, msg ...interface{}) {
doLog(ctx, nil, log.Severity_Error, msg...)
}
func LogErrorInner(ctx context.Context, inner error, msg ...interface{}) {
2024-07-15 15:34:04 +03:30
doLog(ctx, inner, log.Severity_Error, msg...)
2024-06-29 14:32:57 -04:00
}
func doLog(ctx context.Context, inner error, severity log.Severity, msg ...interface{}) {
2026-09-20 17:00:49 +08:00
if log.GetSeverity() < severity {
return
}
2024-06-29 14:32:57 -04:00
pc, _, _, _ := runtime.Caller(2)
details := runtime.FuncForPC(pc).Name()
if len(details) >= trim {
details = details[trim:]
}
i := strings.Index(details, ".")
if i > 0 {
details = details[:i]
}
err := &Error{
2026-09-20 17:00:49 +08:00
message: msg,
caller: details,
inner: inner,
2020-11-25 19:01:53 +08:00
}
2024-06-29 14:32:57 -04:00
if ctx != nil && ctx != context.Background() {
id := uint32(c.IDFromContext(ctx))
if id > 0 {
err.prefix = append(err.prefix, id)
}
}
log.Record(&log.GeneralMessage{
2026-09-20 17:00:49 +08:00
Severity: severity,
2024-06-29 14:32:57 -04:00
Content: err,
})
2020-11-25 19:01:53 +08:00
}
// Cause returns the root cause of this error.
func Cause(err error) error {
if err == nil {
return nil
}
L:
for {
switch inner := err.(type) {
case hasInnerError:
2022-06-01 11:03:06 +08:00
if inner.Unwrap() == nil {
2020-11-25 19:01:53 +08:00
break L
}
2022-06-01 11:03:06 +08:00
err = inner.Unwrap()
2020-11-25 19:01:53 +08:00
default:
break L
}
}
return err
}