mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-29 16:58:34 +00:00
v1.0.0
This commit is contained in:
parent
47d23e9972
commit
c7f7c08ead
711 changed files with 82154 additions and 2 deletions
45
common/errors/errorgen/main.go
Normal file
45
common/errors/errorgen/main.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/xtls/xray-core/v1/common"
|
||||
)
|
||||
|
||||
func main() {
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
fmt.Println("can not get current working directory")
|
||||
os.Exit(1)
|
||||
}
|
||||
pkg := filepath.Base(pwd)
|
||||
if pkg == "xray-core" {
|
||||
pkg = "core"
|
||||
}
|
||||
|
||||
moduleName, gmnErr := common.GetModuleName(pwd)
|
||||
if gmnErr != nil {
|
||||
fmt.Println("can not get module path", gmnErr)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
file, err := os.OpenFile("errors.generated.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to generate errors.generated.go: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
fmt.Fprintln(file, "package", pkg)
|
||||
fmt.Fprintln(file, "")
|
||||
fmt.Fprintln(file, "import \""+moduleName+"/common/errors\"")
|
||||
fmt.Fprintln(file, "")
|
||||
fmt.Fprintln(file, "type errPathObjHolder struct{}")
|
||||
fmt.Fprintln(file, "")
|
||||
fmt.Fprintln(file, "func newError(values ...interface{}) *errors.Error {")
|
||||
fmt.Fprintln(file, " return errors.New(values...).WithPathObj(errPathObjHolder{})")
|
||||
fmt.Fprintln(file, "}")
|
||||
}
|
195
common/errors/errors.go
Normal file
195
common/errors/errors.go
Normal file
|
@ -0,0 +1,195 @@
|
|||
// Package errors is a drop-in replacement for Golang lib 'errors'.
|
||||
package errors // import "github.com/xtls/xray-core/v1/common/errors"
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/xtls/xray-core/v1/common/log"
|
||||
"github.com/xtls/xray-core/v1/common/serial"
|
||||
)
|
||||
|
||||
type hasInnerError interface {
|
||||
// Inner returns the underlying error of this one.
|
||||
Inner() error
|
||||
}
|
||||
|
||||
type hasSeverity interface {
|
||||
Severity() log.Severity
|
||||
}
|
||||
|
||||
// Error is an error object with underlying error.
|
||||
type Error struct {
|
||||
pathObj interface{}
|
||||
prefix []interface{}
|
||||
message []interface{}
|
||||
inner error
|
||||
severity log.Severity
|
||||
}
|
||||
|
||||
func (err *Error) WithPathObj(obj interface{}) *Error {
|
||||
err.pathObj = obj
|
||||
return err
|
||||
}
|
||||
|
||||
func (err *Error) pkgPath() string {
|
||||
if err.pathObj == nil {
|
||||
return ""
|
||||
}
|
||||
return reflect.TypeOf(err.pathObj).PkgPath()
|
||||
}
|
||||
|
||||
// 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("] ")
|
||||
}
|
||||
|
||||
path := err.pkgPath()
|
||||
if len(path) > 0 {
|
||||
builder.WriteString(path)
|
||||
builder.WriteString(": ")
|
||||
}
|
||||
|
||||
msg := serial.Concat(err.message...)
|
||||
builder.WriteString(msg)
|
||||
|
||||
if err.inner != nil {
|
||||
builder.WriteString(" > ")
|
||||
builder.WriteString(err.inner.Error())
|
||||
}
|
||||
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// Inner implements hasInnerError.Inner()
|
||||
func (err *Error) Inner() error {
|
||||
if err.inner == nil {
|
||||
return nil
|
||||
}
|
||||
return err.inner
|
||||
}
|
||||
|
||||
func (err *Error) Base(e error) *Error {
|
||||
err.inner = e
|
||||
return err
|
||||
}
|
||||
|
||||
func (err *Error) atSeverity(s log.Severity) *Error {
|
||||
err.severity = s
|
||||
return err
|
||||
}
|
||||
|
||||
func (err *Error) Severity() log.Severity {
|
||||
if err.inner == nil {
|
||||
return err.severity
|
||||
}
|
||||
|
||||
if s, ok := err.inner.(hasSeverity); ok {
|
||||
as := s.Severity()
|
||||
if as < err.severity {
|
||||
return as
|
||||
}
|
||||
}
|
||||
|
||||
return err.severity
|
||||
}
|
||||
|
||||
// AtDebug sets the severity to debug.
|
||||
func (err *Error) AtDebug() *Error {
|
||||
return err.atSeverity(log.Severity_Debug)
|
||||
}
|
||||
|
||||
// AtInfo sets the severity to info.
|
||||
func (err *Error) AtInfo() *Error {
|
||||
return err.atSeverity(log.Severity_Info)
|
||||
}
|
||||
|
||||
// AtWarning sets the severity to warning.
|
||||
func (err *Error) AtWarning() *Error {
|
||||
return err.atSeverity(log.Severity_Warning)
|
||||
}
|
||||
|
||||
// AtError sets the severity to error.
|
||||
func (err *Error) AtError() *Error {
|
||||
return err.atSeverity(log.Severity_Error)
|
||||
}
|
||||
|
||||
// String returns the string representation of this error.
|
||||
func (err *Error) String() string {
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
// WriteToLog writes current error into log.
|
||||
func (err *Error) WriteToLog(opts ...ExportOption) {
|
||||
var holder ExportOptionHolder
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(&holder)
|
||||
}
|
||||
|
||||
if holder.SessionID > 0 {
|
||||
err.prefix = append(err.prefix, holder.SessionID)
|
||||
}
|
||||
|
||||
log.Record(&log.GeneralMessage{
|
||||
Severity: GetSeverity(err),
|
||||
Content: err,
|
||||
})
|
||||
}
|
||||
|
||||
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 {
|
||||
return &Error{
|
||||
message: msg,
|
||||
severity: log.Severity_Info,
|
||||
}
|
||||
}
|
||||
|
||||
// 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:
|
||||
if inner.Inner() == nil {
|
||||
break L
|
||||
}
|
||||
err = inner.Inner()
|
||||
case *os.PathError:
|
||||
if inner.Err == nil {
|
||||
break L
|
||||
}
|
||||
err = inner.Err
|
||||
case *os.SyscallError:
|
||||
if inner.Err == nil {
|
||||
break L
|
||||
}
|
||||
err = inner.Err
|
||||
default:
|
||||
break L
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// GetSeverity returns the actual severity of the error, including inner errors.
|
||||
func GetSeverity(err error) log.Severity {
|
||||
if s, ok := err.(hasSeverity); ok {
|
||||
return s.Severity()
|
||||
}
|
||||
return log.Severity_Info
|
||||
}
|
62
common/errors/errors_test.go
Normal file
62
common/errors/errors_test.go
Normal file
|
@ -0,0 +1,62 @@
|
|||
package errors_test
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
||||
. "github.com/xtls/xray-core/v1/common/errors"
|
||||
"github.com/xtls/xray-core/v1/common/log"
|
||||
)
|
||||
|
||||
func TestError(t *testing.T) {
|
||||
err := New("TestError")
|
||||
if v := GetSeverity(err); v != log.Severity_Info {
|
||||
t.Error("severity: ", v)
|
||||
}
|
||||
|
||||
err = New("TestError2").Base(io.EOF)
|
||||
if v := GetSeverity(err); v != log.Severity_Info {
|
||||
t.Error("severity: ", v)
|
||||
}
|
||||
|
||||
err = New("TestError3").Base(io.EOF).AtWarning()
|
||||
if v := GetSeverity(err); v != log.Severity_Warning {
|
||||
t.Error("severity: ", v)
|
||||
}
|
||||
|
||||
err = New("TestError4").Base(io.EOF).AtWarning()
|
||||
err = New("TestError5").Base(err)
|
||||
if v := GetSeverity(err); v != log.Severity_Warning {
|
||||
t.Error("severity: ", v)
|
||||
}
|
||||
if v := err.Error(); !strings.Contains(v, "EOF") {
|
||||
t.Error("error: ", v)
|
||||
}
|
||||
}
|
||||
|
||||
type e struct{}
|
||||
|
||||
func TestErrorMessage(t *testing.T) {
|
||||
data := []struct {
|
||||
err error
|
||||
msg string
|
||||
}{
|
||||
{
|
||||
err: New("a").Base(New("b")).WithPathObj(e{}),
|
||||
msg: "github.com/xtls/xray-core/v1/common/errors_test: a > b",
|
||||
},
|
||||
{
|
||||
err: New("a").Base(New("b").WithPathObj(e{})),
|
||||
msg: "a > github.com/xtls/xray-core/v1/common/errors_test: b",
|
||||
},
|
||||
}
|
||||
|
||||
for _, d := range data {
|
||||
if diff := cmp.Diff(d.msg, d.err.Error()); diff != "" {
|
||||
t.Error(diff)
|
||||
}
|
||||
}
|
||||
}
|
30
common/errors/multi_error.go
Normal file
30
common/errors/multi_error.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package errors
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type multiError []error
|
||||
|
||||
func (e multiError) Error() string {
|
||||
var r strings.Builder
|
||||
r.WriteString("multierr: ")
|
||||
for _, err := range e {
|
||||
r.WriteString(err.Error())
|
||||
r.WriteString(" | ")
|
||||
}
|
||||
return r.String()
|
||||
}
|
||||
|
||||
func Combine(maybeError ...error) error {
|
||||
var errs multiError
|
||||
for _, err := range maybeError {
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if len(errs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return errs
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue