Ver código fonte

rewrite error lib

Darien Raymond 9 anos atrás
pai
commit
efb24a4d21
65 arquivos alterados com 251 adições e 132 exclusões
  1. 1 1
      app/dispatcher/impl/default.go
  2. 1 1
      app/dns/server.go
  3. 1 1
      app/proxy/proxy.go
  4. 1 1
      app/router/config.go
  5. 1 2
      app/router/router.go
  6. 2 3
      app/space.go
  7. 29 0
      app/web/config.proto
  8. 1 0
      app/web/file_server.go
  9. 15 0
      app/web/web.go
  10. 1 1
      common/common.go
  11. 80 0
      common/errors/errors.go
  12. 2 1
      common/io/buffered_writer.go
  13. 2 1
      common/io/transport.go
  14. 1 1
      common/loader/type.go
  15. 2 27
      common/log/internal/log_entry.go
  16. 2 2
      common/log/log.go
  17. 1 1
      common/net/port.go
  18. 1 1
      common/protocol/errors.go
  19. 1 1
      common/protocol/id.go
  20. 2 2
      common/protocol/user.go
  21. 1 1
      common/retry/retry.go
  22. 1 1
      common/retry/retry_test.go
  23. 35 0
      common/serial/string.go
  24. 1 1
      common/uuid/uuid.go
  25. 1 1
      proxy/dokodemo/dokodemo.go
  26. 1 1
      proxy/errors.go
  27. 1 1
      proxy/freedom/freedom.go
  28. 2 1
      proxy/http/server.go
  29. 1 2
      proxy/registry/handler_cache.go
  30. 1 1
      proxy/shadowsocks/client.go
  31. 2 3
      proxy/shadowsocks/config.go
  32. 1 1
      proxy/shadowsocks/ota.go
  33. 15 16
      proxy/shadowsocks/protocol.go
  34. 1 2
      proxy/shadowsocks/server.go
  35. 1 1
      proxy/socks/protocol/socks.go
  36. 1 2
      proxy/socks/protocol/socks4.go
  37. 1 1
      proxy/socks/protocol/udp.go
  38. 3 3
      proxy/socks/server.go
  39. 1 1
      proxy/vmess/encoding/commands.go
  40. 1 1
      proxy/vmess/encoding/server.go
  41. 2 1
      proxy/vmess/inbound/inbound.go
  42. 2 1
      proxy/vmess/io/io_test.go
  43. 1 1
      proxy/vmess/io/reader.go
  44. 1 2
      tools/conf/blackhole.go
  45. 1 2
      tools/conf/common.go
  46. 1 2
      tools/conf/loader.go
  47. 1 1
      tools/conf/router.go
  48. 1 2
      tools/conf/shadowsocks.go
  49. 1 2
      tools/conf/socks.go
  50. 1 2
      tools/conf/transport.go
  51. 1 2
      tools/conf/transport_authenticators.go
  52. 1 2
      tools/conf/transport_internet.go
  53. 2 3
      tools/conf/v2ray.go
  54. 1 2
      tools/conf/vmess.go
  55. 1 2
      transport/internet/config.go
  56. 1 2
      transport/internet/dialer.go
  57. 1 1
      transport/internet/internal/sysfd.go
  58. 1 2
      transport/internet/kcp/connection.go
  59. 2 3
      transport/internet/tcp/dialer.go
  60. 1 2
      transport/internet/tcp/hub.go
  61. 1 2
      transport/internet/tcp_hub.go
  62. 1 1
      transport/internet/ws/connection.go
  63. 3 2
      transport/internet/ws/hub.go
  64. 1 1
      transport/internet/ws/stopablehttplistener.go
  65. 2 1
      transport/internet/ws/wsconn.go

+ 1 - 1
app/dispatcher/impl/default.go

@@ -1,11 +1,11 @@
 package impl
 
 import (
-	"errors"
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/proxyman"
 	"v2ray.com/core/app/router"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"

+ 1 - 1
app/dns/server.go

@@ -1,13 +1,13 @@
 package dns
 
 import (
-	"errors"
 	"net"
 	"sync"
 	"time"
 
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dispatcher"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"

+ 1 - 1
app/proxy/proxy.go

@@ -1,13 +1,13 @@
 package proxy
 
 import (
-	"errors"
 	"io"
 	"net"
 	"time"
 
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/proxyman"
+	"v2ray.com/core/common/errors"
 	v2io "v2ray.com/core/common/io"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"

+ 1 - 1
app/router/config.go

@@ -1,9 +1,9 @@
 package router
 
 import (
-	"errors"
 	"net"
 
+	"v2ray.com/core/common/errors"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"
 )

+ 1 - 2
app/router/router.go

@@ -1,10 +1,9 @@
 package router
 
 import (
-	"errors"
-
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dns"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"

+ 2 - 3
app/space.go

@@ -1,9 +1,8 @@
 package app
 
 import (
-	"errors"
-
 	"v2ray.com/core/common"
+	"v2ray.com/core/common/errors"
 )
 
 type ID int
@@ -94,7 +93,7 @@ func (v *spaceImpl) BindApp(id ID, application Application) {
 func (v *spaceImpl) BindFromConfig(name string, config interface{}) error {
 	factory, found := applicationFactoryCache[name]
 	if !found {
-		return errors.New("Space: app not registered: " + name)
+		return errors.New("Space: app not registered: ", name)
 	}
 	app, err := factory.Create(v, config)
 	if err != nil {

+ 29 - 0
app/web/config.proto

@@ -0,0 +1,29 @@
+syntax = "proto3";
+
+package v2ray.core.app.web;
+option go_package = "web";
+option java_package = "com.v2ray.core.app.web";
+option java_outer_classname = "ConfigProto";
+
+import "v2ray.com/core/common/loader/type.proto";
+
+message FileServer {
+  message Entry {
+    oneof FileOrDir {
+      string File = 1;
+      string Directory = 2;
+    }
+    string path = 3;
+  }
+
+  repeated Entry entry = 1;
+}
+
+message Server {
+  repeated string domain = 1;
+  v2ray.core.common.loader.TypedSettings settings = 2;
+}
+
+message Config {
+  repeated Server server = 1;
+}

+ 1 - 0
app/web/file_server.go

@@ -0,0 +1 @@
+package web

+ 15 - 0
app/web/web.go

@@ -0,0 +1,15 @@
+package web
+
+import (
+	"v2ray.com/core/app"
+	"v2ray.com/core/common"
+)
+
+const (
+	APP_ID = app.ID(8)
+)
+
+type Server interface {
+	common.Releasable
+	Handle()
+}

+ 1 - 1
common/common.go

@@ -3,7 +3,7 @@
 package common
 
 import (
-	"errors"
+	"v2ray.com/core/common/errors"
 )
 
 var (

+ 80 - 0
common/errors/errors.go

@@ -0,0 +1,80 @@
+package errors
+
+import (
+	"fmt"
+	"v2ray.com/core/common/serial"
+)
+
+type HasInnerError interface {
+	Inner() error
+}
+
+type Error struct {
+	message string
+	inner   error
+}
+
+func (v *Error) Error() string {
+	return v.message
+}
+
+func (v *Error) Inner() error {
+	if v.inner == nil {
+		return nil
+	}
+	return v.inner
+}
+
+func New(msg ...interface{}) error {
+	return &Error{
+		message: serial.ToString(msg),
+	}
+}
+
+func Base(err error) ErrorBuilder {
+	return ErrorBuilder{
+		error: err,
+	}
+}
+
+func Cause(err error) error {
+	if err == nil {
+		return nil
+	}
+	for {
+		inner, ok := err.(HasInnerError)
+		if !ok {
+			break
+		}
+		if inner.Inner() == nil {
+			break
+		}
+		err = inner.Inner()
+	}
+	return err
+}
+
+type ErrorBuilder struct {
+	error
+}
+
+func (v ErrorBuilder) Message(msg ...interface{}) error {
+	if v.error == nil {
+		return nil
+	}
+
+	return &Error{
+		message: serial.ToString(msg) + " > " + v.error.Error(),
+		inner:   v.error,
+	}
+}
+
+func (v ErrorBuilder) Format(format string, values ...interface{}) error {
+	if v.error == nil {
+		return nil
+	}
+	return &Error{
+		message: fmt.Sprintf(format, values...) + " > " + v.error.Error(),
+		inner:   v.error,
+	}
+}

+ 2 - 1
common/io/buffered_writer.go

@@ -4,6 +4,7 @@ import (
 	"io"
 	"sync"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/errors"
 )
 
 type BufferedWriter struct {
@@ -34,7 +35,7 @@ func (v *BufferedWriter) ReadFrom(reader io.Reader) (int64, error) {
 		nBytes, err := v.buffer.FillFrom(reader)
 		totalBytes += int64(nBytes)
 		if err != nil {
-			if err == io.EOF {
+			if errors.Cause(err) == io.EOF {
 				return totalBytes, nil
 			}
 			return totalBytes, err

+ 2 - 1
common/io/transport.go

@@ -2,6 +2,7 @@ package io
 
 import (
 	"io"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 )
 
@@ -29,7 +30,7 @@ func Pipe(reader Reader, writer Writer) error {
 
 func PipeUntilEOF(reader Reader, writer Writer) error {
 	err := Pipe(reader, writer)
-	if err != nil && err != io.EOF {
+	if err != nil && errors.Cause(err) != io.EOF {
 		return err
 	}
 	return nil

+ 1 - 1
common/loader/type.go

@@ -1,10 +1,10 @@
 package loader
 
 import (
-	"errors"
 	"reflect"
 
 	"github.com/golang/protobuf/proto"
+	"v2ray.com/core/common/errors"
 )
 
 func NewTypedSettings(message proto.Message) *TypedSettings {

+ 2 - 27
common/log/internal/log_entry.go

@@ -8,26 +8,6 @@ import (
 	"v2ray.com/core/common/serial"
 )
 
-func InterfaceToString(value interface{}) string {
-	if value == nil {
-		return " "
-	}
-	switch value := value.(type) {
-	case string:
-		return value
-	case *string:
-		return *value
-	case fmt.Stringer:
-		return value.String()
-	case error:
-		return value.Error()
-	case []byte:
-		return serial.BytesToHexString(value)
-	default:
-		return fmt.Sprintf("%+v", value)
-	}
-}
-
 type LogEntry interface {
 	common.Releasable
 	fmt.Stringer
@@ -46,12 +26,7 @@ func (v *ErrorLog) Release() {
 }
 
 func (v *ErrorLog) String() string {
-	values := make([]string, len(v.Values)+1)
-	values[0] = v.Prefix
-	for i, value := range v.Values {
-		values[i+1] = InterfaceToString(value)
-	}
-	return strings.Join(values, "")
+	return v.Prefix + serial.Concat(v.Values...)
 }
 
 type AccessLog struct {
@@ -68,5 +43,5 @@ func (v *AccessLog) Release() {
 }
 
 func (v *AccessLog) String() string {
-	return strings.Join([]string{InterfaceToString(v.From), v.Status, InterfaceToString(v.To), InterfaceToString(v.Reason)}, " ")
+	return strings.Join([]string{serial.ToString(v.From), v.Status, serial.ToString(v.To), serial.ToString(v.Reason)}, " ")
 }

+ 2 - 2
common/log/log.go

@@ -1,7 +1,7 @@
 package log
 
 import (
-	"errors"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log/internal"
 )
 
@@ -39,7 +39,7 @@ func SetLogLevel(level LogLevel) {
 func InitErrorLogger(file string) error {
 	logger, err := internal.NewFileLogWriter(file)
 	if err != nil {
-		return errors.New("Log:Failed to create error logger on file (" + file + "): " + err.Error())
+		return errors.Base(err).Message("Log: Failed to create error logger on file (", file, ")")
 	}
 	streamLoggerInstance = logger
 	return nil

+ 1 - 1
common/net/port.go

@@ -1,9 +1,9 @@
 package net
 
 import (
-	"errors"
 	"strconv"
 
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/serial"
 )
 

+ 1 - 1
common/protocol/errors.go

@@ -1,7 +1,7 @@
 package protocol
 
 import (
-	"errors"
+	"v2ray.com/core/common/errors"
 )
 
 var (

+ 1 - 1
common/protocol/id.go

@@ -3,9 +3,9 @@ package protocol
 import (
 	"crypto/hmac"
 	"crypto/md5"
-	"errors"
 	"hash"
 
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/uuid"
 )
 

+ 2 - 2
common/protocol/user.go

@@ -1,7 +1,7 @@
 package protocol
 
 import (
-	"errors"
+	"v2ray.com/core/common/errors"
 )
 
 var (
@@ -26,7 +26,7 @@ func (v *User) GetTypedAccount() (Account, error) {
 	if account, ok := rawAccount.(Account); ok {
 		return account, nil
 	}
-	return nil, errors.New("Unknown account type: " + v.Account.Type)
+	return nil, errors.New("Unknown account type: ", v.Account.Type)
 }
 
 func (v *User) GetSettings() UserSettings {

+ 1 - 1
common/retry/retry.go

@@ -1,8 +1,8 @@
 package retry
 
 import (
-	"errors"
 	"time"
+	"v2ray.com/core/common/errors"
 )
 
 var (

+ 1 - 1
common/retry/retry_test.go

@@ -1,10 +1,10 @@
 package retry_test
 
 import (
-	"errors"
 	"testing"
 	"time"
 
+	"v2ray.com/core/common/errors"
 	. "v2ray.com/core/common/retry"
 	"v2ray.com/core/testing/assert"
 )

+ 35 - 0
common/serial/string.go

@@ -0,0 +1,35 @@
+package serial
+
+import (
+	"fmt"
+	"strings"
+)
+
+func ToString(v interface{}) string {
+	if v == nil {
+		return " "
+	}
+
+	switch value := v.(type) {
+	case string:
+		return value
+	case *string:
+		return *value
+	case fmt.Stringer:
+		return value.String()
+	case error:
+		return value.Error()
+	case []byte:
+		return BytesToHexString(value)
+	default:
+		return fmt.Sprintf("%+v", value)
+	}
+}
+
+func Concat(v ...interface{}) string {
+	values := make([]string, len(v))
+	for i, value := range v {
+		values[i] = ToString(value)
+	}
+	return strings.Join(values, "")
+}

+ 1 - 1
common/uuid/uuid.go

@@ -5,7 +5,7 @@ import (
 	"crypto/md5"
 	"crypto/rand"
 	"encoding/hex"
-	"errors"
+	"v2ray.com/core/common/errors"
 )
 
 var (

+ 1 - 1
proxy/dokodemo/dokodemo.go

@@ -3,10 +3,10 @@ package dokodemo
 import (
 	"sync"
 
-	"errors"
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/errors"
 	v2io "v2ray.com/core/common/io"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"

+ 1 - 1
proxy/errors.go

@@ -1,7 +1,7 @@
 package proxy
 
 import (
-	"errors"
+	"v2ray.com/core/common/errors"
 )
 
 var (

+ 1 - 1
proxy/freedom/freedom.go

@@ -1,12 +1,12 @@
 package freedom
 
 import (
-	"errors"
 	"io"
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dns"
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/dice"
+	"v2ray.com/core/common/errors"
 	v2io "v2ray.com/core/common/io"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"

+ 2 - 1
proxy/http/server.go

@@ -12,6 +12,7 @@ import (
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/common"
+	"v2ray.com/core/common/errors"
 	v2io "v2ray.com/core/common/io"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
@@ -101,7 +102,7 @@ func (v *Server) handleConnection(conn internet.Connection) {
 
 	request, err := http.ReadRequest(reader)
 	if err != nil {
-		if err != io.EOF {
+		if errors.Cause(err) != io.EOF {
 			log.Warning("HTTP: Failed to read http request: ", err)
 		}
 		return

+ 1 - 2
proxy/registry/handler_cache.go

@@ -1,10 +1,9 @@
 package registry
 
 import (
-	"errors"
-
 	"v2ray.com/core/app"
 	"v2ray.com/core/common"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/transport/internet"
 )

+ 1 - 1
proxy/shadowsocks/client.go

@@ -111,7 +111,7 @@ func (v *Client) Dispatch(destination v2net.Destination, payload *alloc.Buffer,
 
 			responseReader, err := ReadTCPResponse(user, conn)
 			if err != nil {
-				log.Warning("Shadowsocks|Client: Failed to read response: " + err.Error())
+				log.Warning("Shadowsocks|Client: Failed to read response: ", err)
 				return
 			}
 

+ 2 - 3
proxy/shadowsocks/config.go

@@ -4,9 +4,8 @@ import (
 	"bytes"
 	"crypto/cipher"
 	"crypto/md5"
-	"errors"
-
 	"v2ray.com/core/common/crypto"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/protocol"
 )
 
@@ -41,7 +40,7 @@ func (v *Account) GetCipher() (Cipher, error) {
 func (v *Account) AsAccount() (protocol.Account, error) {
 	cipher, err := v.GetCipher()
 	if err != nil {
-		return nil, err
+		return nil, errors.Base(err).Message("Shadowsocks|Account: Failed to get cipher.")
 	}
 	return &ShadowsocksAccount{
 		Cipher:      cipher,

+ 1 - 1
proxy/shadowsocks/ota.go

@@ -4,9 +4,9 @@ import (
 	"bytes"
 	"crypto/hmac"
 	"crypto/sha1"
-	"errors"
 	"io"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/serial"
 )
 

+ 15 - 16
proxy/shadowsocks/protocol.go

@@ -3,11 +3,10 @@ package shadowsocks
 import (
 	"bytes"
 	"crypto/rand"
-	"errors"
 	"io"
-
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/crypto"
+	"v2ray.com/core/common/errors"
 	v2io "v2ray.com/core/common/io"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
@@ -25,7 +24,7 @@ const (
 func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHeader, v2io.Reader, error) {
 	rawAccount, err := user.GetTypedAccount()
 	if err != nil {
-		return nil, nil, errors.New("Shadowsocks|TCP: Failed to parse account: " + err.Error())
+		return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to parse account.")
 	}
 	account := rawAccount.(*ShadowsocksAccount)
 
@@ -35,14 +34,14 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
 	ivLen := account.Cipher.IVSize()
 	_, err = io.ReadFull(reader, buffer.Value[:ivLen])
 	if err != nil {
-		return nil, nil, errors.New("Shadowsocks|TCP: Failed to read IV: " + err.Error())
+		return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IV.")
 	}
 
 	iv := append([]byte(nil), buffer.Value[:ivLen]...)
 
 	stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
 	if err != nil {
-		return nil, nil, errors.New("Shadowsocks|TCP: Failed to initialize decoding stream: " + err.Error())
+		return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to initialize decoding stream.")
 	}
 	reader = crypto.NewCryptionReader(stream, reader)
 
@@ -56,7 +55,7 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
 	lenBuffer := 1
 	_, err = io.ReadFull(reader, buffer.Value[:1])
 	if err != nil {
-		return nil, nil, errors.New("Shadowsocks|TCP: Failed to read address type: " + err.Error())
+		return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read address type.")
 	}
 
 	addrType := (buffer.Value[0] & 0x0F)
@@ -76,32 +75,32 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
 	case AddrTypeIPv4:
 		_, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+4])
 		if err != nil {
-			return nil, nil, errors.New("Shadowsocks|TCP: Failed to read IPv4 address: " + err.Error())
+			return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IPv4 address.")
 		}
 		request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+4])
 		lenBuffer += 4
 	case AddrTypeIPv6:
 		_, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+16])
 		if err != nil {
-			return nil, nil, errors.New("Shadowsocks|TCP: Failed to read IPv6 address: " + err.Error())
+			return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IPv6 address.")
 		}
 		request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+16])
 		lenBuffer += 16
 	case AddrTypeDomain:
 		_, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+1])
 		if err != nil {
-			return nil, nil, errors.New("Shadowsocks|TCP: Failed to read domain lenth: " + err.Error())
+			return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read domain lenth.")
 		}
 		domainLength := int(buffer.Value[lenBuffer])
 		lenBuffer++
 		_, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+domainLength])
 		if err != nil {
-			return nil, nil, errors.New("Shadowsocks|TCP: Failed to read domain: " + err.Error())
+			return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read domain.")
 		}
 		request.Address = v2net.DomainAddress(string(buffer.Value[lenBuffer : lenBuffer+domainLength]))
 		lenBuffer += domainLength
 	default:
-		return nil, nil, errors.New("Shadowsocks|TCP: Unknown address type.")
+		return nil, nil, errors.New("Shadowsocks|TCP: Unknown address type: ", addrType)
 	}
 
 	_, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+2])
@@ -139,7 +138,7 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (v2io.Wr
 	user := request.User
 	rawAccount, err := user.GetTypedAccount()
 	if err != nil {
-		return nil, errors.New("Shadowsocks|TCP: Failed to parse account: " + err.Error())
+		return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to parse account.")
 	}
 	account := rawAccount.(*ShadowsocksAccount)
 
@@ -147,12 +146,12 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (v2io.Wr
 	rand.Read(iv)
 	_, err = writer.Write(iv)
 	if err != nil {
-		return nil, errors.New("Shadowsocks|TCP: Failed to write IV: " + err.Error())
+		return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to write IV.")
 	}
 
 	stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
 	if err != nil {
-		return nil, errors.New("Shadowsocks|TCP: Failed to create encoding stream: " + err.Error())
+		return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to create encoding stream.")
 	}
 
 	writer = crypto.NewCryptionWriter(stream, writer)
@@ -170,7 +169,7 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (v2io.Wr
 		header.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain())))
 		header.Append([]byte(request.Address.Domain()))
 	default:
-		return nil, errors.New("Shadowsocks|TCP: Unsupported address type. ")
+		return nil, errors.New("Shadowsocks|TCP: Unsupported address type: ", request.Address.Family())
 	}
 
 	header.AppendUint16(uint16(request.Port))
@@ -184,7 +183,7 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (v2io.Wr
 
 	_, err = writer.Write(header.Value)
 	if err != nil {
-		return nil, errors.New("Shadowsocks|TCP: Failed to write header: " + err.Error())
+		return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to write header.")
 	}
 
 	var chunkWriter v2io.Writer

+ 1 - 2
proxy/shadowsocks/server.go

@@ -3,12 +3,11 @@ package shadowsocks
 
 import (
 	"sync"
-
-	"errors"
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/errors"
 	v2io "v2ray.com/core/common/io"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"

+ 1 - 1
proxy/socks/protocol/socks.go

@@ -1,10 +1,10 @@
 package protocol
 
 import (
-	"errors"
 	"fmt"
 	"io"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"

+ 1 - 2
proxy/socks/protocol/socks4.go

@@ -1,9 +1,8 @@
 package protocol
 
 import (
-	"errors"
 	"io"
-
+	"v2ray.com/core/common/errors"
 	v2net "v2ray.com/core/common/net"
 )
 

+ 1 - 1
proxy/socks/protocol/udp.go

@@ -1,9 +1,9 @@
 package protocol
 
 import (
-	"errors"
 	"fmt"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/errors"
 	v2net "v2ray.com/core/common/net"
 )
 

+ 3 - 3
proxy/socks/server.go

@@ -1,13 +1,13 @@
 package socks
 
 import (
-	"errors"
 	"io"
 	"sync"
 	"time"
 
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dispatcher"
+	"v2ray.com/core/common/errors"
 	v2io "v2ray.com/core/common/io"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
@@ -112,8 +112,8 @@ func (v *Server) handleConnection(connection internet.Connection) {
 	defer writer.Release()
 
 	auth, auth4, err := protocol.ReadAuthentication(reader)
-	if err != nil && err != protocol.Socks4Downgrade {
-		if err != io.EOF {
+	if err != nil && errors.Cause(err) != protocol.Socks4Downgrade {
+		if errors.Cause(err) != io.EOF {
 			log.Warning("Socks: failed to read authentication: ", err)
 		}
 		return

+ 1 - 1
proxy/vmess/encoding/commands.go

@@ -1,10 +1,10 @@
 package encoding
 
 import (
-	"errors"
 	"io"
 
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/errors"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/serial"

+ 1 - 1
proxy/vmess/encoding/server.go

@@ -2,10 +2,10 @@ package encoding
 
 import (
 	"crypto/md5"
-	"errors"
 	"hash/fnv"
 	"io"
 	"v2ray.com/core/common/crypto"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"

+ 2 - 1
proxy/vmess/inbound/inbound.go

@@ -9,6 +9,7 @@ import (
 	"v2ray.com/core/app/proxyman"
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/errors"
 	v2io "v2ray.com/core/common/io"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
@@ -154,7 +155,7 @@ func (v *VMessInboundHandler) HandleConnection(connection internet.Connection) {
 	v.RUnlock()
 
 	if err != nil {
-		if err != io.EOF {
+		if errors.Cause(err) != io.EOF {
 			log.Access(connection.RemoteAddr(), "", log.AccessRejected, err)
 			log.Info("VMessIn: Invalid request from ", connection.RemoteAddr(), ": ", err)
 		}

+ 2 - 1
proxy/vmess/io/io_test.go

@@ -7,6 +7,7 @@ import (
 	"testing"
 
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/errors"
 	v2io "v2ray.com/core/common/io"
 	. "v2ray.com/core/proxy/vmess/io"
 	"v2ray.com/core/testing/assert"
@@ -68,7 +69,7 @@ func TestLargeIO(t *testing.T) {
 	reader := NewAuthChunkReader(chunckContent)
 	for {
 		buffer, err := reader.Read()
-		if err == io.EOF {
+		if errors.Cause(err) == io.EOF {
 			break
 		}
 		assert.Error(err).IsNil()

+ 1 - 1
proxy/vmess/io/reader.go

@@ -1,11 +1,11 @@
 package io
 
 import (
-	"errors"
 	"hash"
 	"hash/fnv"
 	"io"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/serial"
 )
 

+ 1 - 2
tools/conf/blackhole.go

@@ -2,8 +2,7 @@ package conf
 
 import (
 	"encoding/json"
-	"errors"
-
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/proxy/blackhole"
 )

+ 1 - 2
tools/conf/common.go

@@ -2,9 +2,8 @@ package conf
 
 import (
 	"encoding/json"
-	"errors"
-
 	"strings"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"

+ 1 - 2
tools/conf/loader.go

@@ -2,9 +2,8 @@ package conf
 
 import (
 	"encoding/json"
-	"errors"
-
 	"v2ray.com/core/common"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 )
 

+ 1 - 1
tools/conf/router.go

@@ -2,11 +2,11 @@ package conf
 
 import (
 	"encoding/json"
-	"errors"
 	"strconv"
 	"strings"
 
 	"v2ray.com/core/app/router"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/tools/geoip"

+ 1 - 2
tools/conf/shadowsocks.go

@@ -1,9 +1,8 @@
 package conf
 
 import (
-	"errors"
 	"strings"
-
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/proxy/shadowsocks"

+ 1 - 2
tools/conf/socks.go

@@ -2,8 +2,7 @@ package conf
 
 import (
 	"encoding/json"
-	"errors"
-
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/proxy/socks"

+ 1 - 2
tools/conf/transport.go

@@ -1,8 +1,7 @@
 package conf
 
 import (
-	"errors"
-
+	"v2ray.com/core/common/errors"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport"
 	"v2ray.com/core/transport/internet"

+ 1 - 2
tools/conf/transport_authenticators.go

@@ -1,8 +1,7 @@
 package conf
 
 import (
-	"errors"
-
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/transport/internet/authenticators/http"
 	"v2ray.com/core/transport/internet/authenticators/noop"

+ 1 - 2
tools/conf/transport_internet.go

@@ -2,11 +2,10 @@ package conf
 
 import (
 	"encoding/json"
-	"errors"
 	"fmt"
 	"io/ioutil"
-
 	"strings"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/loader"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"

+ 2 - 3
tools/conf/v2ray.go

@@ -2,11 +2,10 @@ package conf
 
 import (
 	"encoding/json"
-	"errors"
-	"strings"
-
 	"io"
+	"strings"
 	"v2ray.com/core"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/loader"
 	v2net "v2ray.com/core/common/net"
 )

+ 1 - 2
tools/conf/vmess.go

@@ -2,8 +2,7 @@ package conf
 
 import (
 	"encoding/json"
-	"errors"
-
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/loader"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"

+ 1 - 2
transport/internet/config.go

@@ -1,8 +1,7 @@
 package internet
 
 import (
-	"errors"
-
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"

+ 1 - 2
transport/internet/dialer.go

@@ -1,9 +1,8 @@
 package internet
 
 import (
-	"errors"
 	"net"
-
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 )

+ 1 - 1
transport/internet/internal/sysfd.go

@@ -1,9 +1,9 @@
 package internal
 
 import (
-	"errors"
 	"net"
 	"reflect"
+	"v2ray.com/core/common/errors"
 )
 
 var (

+ 1 - 2
transport/internet/kcp/connection.go

@@ -1,13 +1,12 @@
 package kcp
 
 import (
-	"errors"
 	"io"
 	"net"
 	"sync"
 	"sync/atomic"
 	"time"
-
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/predicate"
 	"v2ray.com/core/transport/internet"

+ 2 - 3
transport/internet/tcp/dialer.go

@@ -1,10 +1,9 @@
 package tcp
 
 import (
-	"errors"
-	"net"
-
 	"crypto/tls"
+	"net"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"

+ 1 - 2
transport/internet/tcp/hub.go

@@ -2,11 +2,10 @@ package tcp
 
 import (
 	"crypto/tls"
-	"errors"
 	"net"
 	"sync"
 	"time"
-
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"

+ 1 - 2
transport/internet/tcp_hub.go

@@ -1,10 +1,9 @@
 package internet
 
 import (
-	"errors"
 	"net"
 	"sync"
-
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/retry"

+ 1 - 1
transport/internet/ws/connection.go

@@ -1,10 +1,10 @@
 package ws
 
 import (
-	"errors"
 	"io"
 	"net"
 	"time"
+	"v2ray.com/core/common/errors"
 )
 
 var (

+ 3 - 2
transport/internet/ws/hub.go

@@ -2,18 +2,19 @@ package ws
 
 import (
 	"crypto/tls"
-	"errors"
 	"net"
 	"net/http"
 	"strconv"
 	"sync"
 	"time"
 
-	"github.com/gorilla/websocket"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 	v2tls "v2ray.com/core/transport/internet/tls"
+
+	"github.com/gorilla/websocket"
 )
 
 var (

+ 1 - 1
transport/internet/ws/stopablehttplistener.go

@@ -1,8 +1,8 @@
 package ws
 
 import (
-	"errors"
 	"net"
+	"v2ray.com/core/common/errors"
 )
 
 type StoppableListener struct {

+ 2 - 1
transport/internet/ws/wsconn.go

@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/gorilla/websocket"
+	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/log"
 )
 
@@ -64,7 +65,7 @@ func (ws *wsconn) readNext(b []byte) (n int, err error) {
 		return n, err
 	}
 
-	if err == io.EOF {
+	if errors.Cause(err) == io.EOF {
 		ws.readBuffer = nil
 		if n == 0 {
 			return ws.readNext(b)