improve gerror/glog

This commit is contained in:
John
2019-06-29 23:35:32 +08:00
parent 58a405bfa8
commit 009ce9063e
14 changed files with 130 additions and 137 deletions

View File

@ -13,7 +13,7 @@ import (
"io"
"os"
"github.com/gogf/gf/g/internal/errors"
"github.com/gogf/gf/g/errors/gerror"
"github.com/gogf/gf/g/util/gconv"
)
@ -40,7 +40,7 @@ func EncryptFile(path string) (encrypt string, err error) {
return "", err
}
defer func() {
err = errors.Wrap(f.Close(), "file closing error")
err = gerror.Wrap(f.Close(), "file closing error")
}()
h := md5.New()
_, err = io.Copy(h, f)

View File

@ -13,7 +13,7 @@ import (
"io"
"os"
"github.com/gogf/gf/g/internal/errors"
"github.com/gogf/gf/g/errors/gerror"
"github.com/gogf/gf/g/util/gconv"
)
@ -37,7 +37,7 @@ func EncryptFile(path string) (encrypt string, err error) {
return "", err
}
defer func() {
err = errors.Wrap(f.Close(), "file closing error")
err = gerror.Wrap(f.Close(), "file closing error")
}()
h := sha1.New()
_, err = io.Copy(h, f)

View File

@ -10,6 +10,7 @@ package gerror
import (
"bytes"
"fmt"
"io"
"runtime"
"strings"
@ -17,14 +18,21 @@ import (
"github.com/pkg/errors"
)
// stacker is an interface for errors.StackTrace.
type stacker interface {
StackTrace() errors.StackTrace
}
// stacker is an interface for errors.Cause.
type causer interface {
Cause() error
}
// stackError is custom error for additional features.
type stackError struct {
error
}
const (
gFILTER_KEY = "/g/errors/gerror/gerror.go"
)
@ -53,7 +61,7 @@ func NewText(text string) error {
if text == "" {
return nil
}
return errors.New(text)
return &stackError{errors.New(text)}
}
// Wrap wraps error with text.
@ -61,14 +69,14 @@ func Wrap(err error, text string) error {
if err == nil {
return nil
}
return errors.Wrap(err, text)
return &stackError{errors.Wrap(err, text)}
}
// Wrapf returns an error annotating err with a stack trace
// at the point Wrapf is called, and the format specifier.
// If err is nil, Wrapf returns nil.
func Wrapf(err error, format string, args ...interface{}) error {
return errors.Wrapf(err, format, args...)
return &stackError{errors.Wrapf(err, format, args...)}
}
// Cause returns the underlying cause of the error, if possible.
@ -83,10 +91,31 @@ func Wrapf(err error, format string, args ...interface{}) error {
// be returned. If the error is nil, nil will be returned without further
// investigation.
func Cause(err error) error {
return errors.Cause(err)
return &stackError{errors.Cause(err)}
}
// Format formats the frame according to the fmt.Formatter interface.
//
// %v, %s : Print the error string;
// %+v, %+s : Print the error stack list;
func (err *stackError) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
switch {
case s.Flag('+'):
io.WriteString(s, Stack(err.error))
default:
io.WriteString(s, err.Error())
}
}
}
func (err *stackError) Cause() error {
return err.error
}
// Stack returns the stack callers as string.
// It returns am empty string id the <err> does not support stacks.
func Stack(err error) string {
if err == nil {
return ""

View File

@ -9,7 +9,7 @@ package gerror_test
import (
"testing"
"github.com/gogf/gf/g/internal/errors"
"github.com/gogf/gf/g/errors/gerror"
"github.com/gogf/gf/g/test/gtest"
)
@ -23,16 +23,16 @@ func nilError() error {
func Test_Nil(t *testing.T) {
gtest.Case(t, func() {
gtest.Assert(errors.New(interfaceNil()), nil)
gtest.Assert(errors.Wrap(nilError(), "test"), nil)
gtest.Assert(gerror.New(interfaceNil()), nil)
gtest.Assert(gerror.Wrap(nilError(), "test"), nil)
})
}
func Test_Wrap(t *testing.T) {
gtest.Case(t, func() {
err := errors.New("1")
err = errors.Wrap(err, "func2 error")
err = errors.Wrap(err, "func3 error")
err := gerror.New("1")
err = gerror.Wrap(err, "func2 error")
err = gerror.Wrap(err, "func3 error")
gtest.AssertNE(err, nil)
gtest.Assert(err.Error(), "func3 error: func2 error: 1")
})

View File

@ -1,48 +0,0 @@
// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
// Package errors provides simple functions to manipulate errors.
//
// This package can be scalable due to https://go.googlesource.com/proposal/+/master/design/go2draft.md.
package errors
import "github.com/gogf/gf/g/util/gconv"
// errorWrapper is a simple wrapper for errors.
type errorWrapper struct {
s string
}
// New returns an error that formats as the given value.
func New(value interface{}) error {
if value == nil {
return nil
}
return NewText(gconv.String(value))
}
// NewText returns an error that formats as the given text.
func NewText(text string) error {
if text == "" {
return nil
}
return &errorWrapper{
s: text,
}
}
// Wrap wraps error with text.
func Wrap(err error, text string) error {
if err == nil {
return nil
}
return NewText(text + ": " + err.Error())
}
// Error implements interface Error.
func (e *errorWrapper) Error() string {
return e.s
}

View File

@ -1,39 +0,0 @@
// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package errors_test
import (
"testing"
"github.com/gogf/gf/g/internal/errors"
"github.com/gogf/gf/g/test/gtest"
)
func interfaceNil() interface{} {
return nil
}
func nilError() error {
return nil
}
func Test_Nil(t *testing.T) {
gtest.Case(t, func() {
gtest.Assert(errors.New(interfaceNil()), nil)
gtest.Assert(errors.Wrap(nilError(), "test"), nil)
})
}
func Test_Wrap(t *testing.T) {
gtest.Case(t, func() {
err := errors.New("1")
err = errors.Wrap(err, "func2 error")
err = errors.Wrap(err, "func3 error")
gtest.AssertNE(err, nil)
gtest.Assert(err.Error(), "func3 error: func2 error: 1")
})
}

View File

@ -14,7 +14,7 @@ import (
"net"
"time"
"github.com/gogf/gf/g/internal/errors"
"github.com/gogf/gf/g/errors/gerror"
)
// 封装的链接对象
@ -209,7 +209,7 @@ func (c *Conn) RecvWithTimeout(length int, timeout time.Duration, retry ...Retry
return nil, err
}
defer func() {
err = errors.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
err = gerror.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
}()
data, err = c.Recv(length, retry...)
return
@ -221,7 +221,7 @@ func (c *Conn) SendWithTimeout(data []byte, timeout time.Duration, retry ...Retr
return err
}
defer func() {
err = errors.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
err = gerror.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
}()
err = c.Send(data, retry...)
return

View File

@ -11,7 +11,7 @@ import (
"fmt"
"time"
"github.com/gogf/gf/g/internal/errors"
"github.com/gogf/gf/g/errors/gerror"
)
const (
@ -74,7 +74,7 @@ func (c *Conn) SendPkgWithTimeout(data []byte, timeout time.Duration, option ...
return err
}
defer func() {
err = errors.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
err = gerror.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
}()
err = c.SendPkg(data, option...)
return
@ -147,7 +147,7 @@ func (c *Conn) RecvPkgWithTimeout(timeout time.Duration, option ...PkgOption) (d
return nil, err
}
defer func() {
err = errors.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
err = gerror.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
}()
data, err = c.RecvPkg(option...)
return

View File

@ -9,10 +9,9 @@ package gtcp
import (
"time"
"github.com/gogf/gf/g/internal/errors"
"github.com/gogf/gf/g/container/gmap"
"github.com/gogf/gf/g/container/gpool"
"github.com/gogf/gf/g/errors/gerror"
)
// 链接池链接对象
@ -122,7 +121,7 @@ func (c *PoolConn) RecvWithTimeout(length int, timeout time.Duration, retry ...R
return nil, err
}
defer func() {
err = errors.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
err = gerror.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
}()
data, err = c.Recv(length, retry...)
return
@ -134,7 +133,7 @@ func (c *PoolConn) SendWithTimeout(data []byte, timeout time.Duration, retry ...
return err
}
defer func() {
err = errors.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
err = gerror.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
}()
err = c.Send(data, retry...)
return

View File

@ -9,7 +9,7 @@ package gtcp
import (
"time"
"github.com/gogf/gf/g/internal/errors"
"github.com/gogf/gf/g/errors/gerror"
)
// 简单协议: (方法覆盖)发送数据
@ -47,7 +47,7 @@ func (c *PoolConn) RecvPkgWithTimeout(timeout time.Duration, option ...PkgOption
return nil, err
}
defer func() {
err = errors.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
err = gerror.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
}()
data, err = c.RecvPkg(option...)
return
@ -59,7 +59,7 @@ func (c *PoolConn) SendPkgWithTimeout(data []byte, timeout time.Duration, option
return err
}
defer func() {
err = errors.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
err = gerror.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
}()
err = c.SendPkg(data, option...)
return

View File

@ -11,7 +11,7 @@ import (
"net"
"time"
"github.com/gogf/gf/g/internal/errors"
"github.com/gogf/gf/g/errors/gerror"
)
// 封装的UDP链接对象
@ -182,7 +182,7 @@ func (c *Conn) RecvWithTimeout(length int, timeout time.Duration, retry ...Retry
return nil, err
}
defer func() {
err = errors.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
err = gerror.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
}()
data, err = c.Recv(length, retry...)
return
@ -194,7 +194,7 @@ func (c *Conn) SendWithTimeout(data []byte, timeout time.Duration, retry ...Retr
return err
}
defer func() {
err = errors.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
err = gerror.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
}()
err = c.Send(data, retry...)
return

View File

@ -12,7 +12,6 @@ import (
"fmt"
"io"
"os"
"runtime"
"strings"
"time"
@ -57,18 +56,6 @@ const (
F_TIME_STD = F_TIME_DATE | F_TIME_MILLI
)
var (
// Default line break.
ln = "\n"
)
func init() {
// Initialize log line breaks depending on underlying os.
if runtime.GOOS == "windows" {
ln = "\r\n"
}
}
// New creates and returns a custom logger.
func New() *Logger {
logger := &Logger{
@ -270,13 +257,25 @@ func (l *Logger) print(std io.Writer, lead string, value ...interface{}) {
buffer.WriteString(l.prefix + " ")
}
}
for k, v := range value {
if k > 0 {
buffer.WriteByte(' ')
tempStr := ""
valueStr := ""
for _, v := range value {
tempStr = gconv.String(v)
if len(valueStr) > 0 {
if valueStr[len(valueStr)-1] == '\n' {
if tempStr[0] == '\n' {
valueStr += tempStr[1:]
} else {
valueStr += tempStr
}
} else {
valueStr += " "
}
} else {
valueStr = tempStr
}
buffer.WriteString(gconv.String(v))
}
buffer.WriteString(ln)
buffer.WriteString(valueStr + "\n")
if l.flags&F_ASYNC > 0 {
asyncPool.Add(func() {
l.printToWriter(std, buffer)
@ -317,7 +316,7 @@ func (l *Logger) printStd(lead string, value ...interface{}) {
func (l *Logger) printErr(lead string, value ...interface{}) {
if l.stStatus == 1 {
if s := l.GetStack(); s != "" {
value = append(value, ln+"Stack:"+ln+s)
value = append(value, "\nStack:\n"+s)
}
}
// In matter of sequence, do not use stderr here, but use the same stdout.
@ -333,7 +332,7 @@ func (l *Logger) format(format string, value ...interface{}) string {
// the optional parameter <skip> specify the skipped stack offset from the end point.
func (l *Logger) PrintStack(skip ...int) {
if s := l.GetStack(skip...); s != "" {
l.Println("Stack:" + ln + s)
l.Println("Stack:\n" + s)
} else {
l.Println()
}

View File

@ -0,0 +1,31 @@
package main
import (
"fmt"
"github.com/pkg/errors"
"github.com/gogf/gf/g/errors/gerror"
)
func Test1() error {
return gerror.New("test")
}
func Test2() error {
return gerror.Wrap(Test1(), "error test1")
}
type stackTracer interface {
StackTrace() errors.StackTrace
}
func main() {
err := Test2()
fmt.Printf("%s\n", err)
fmt.Printf("%v\n", err)
fmt.Printf("%+v\n", err)
fmt.Println(gerror.Stack(err))
return
}

View File

@ -0,0 +1,22 @@
package main
import (
"github.com/gogf/gf/g/os/glog"
"github.com/gogf/gf/g/errors/gerror"
)
func OpenFile() error {
return gerror.New("permission denied")
}
func OpenConfig() error {
return gerror.Wrap(OpenFile(), "configuration file opening failed")
}
func main() {
glog.Println(OpenConfig())
glog.Printf("unexpected error:\n%+s", OpenConfig())
glog.Errorf("unexpected error:\n%+s", OpenConfig())
}