diff --git a/container/gtree/gtree_btree.go b/container/gtree/gtree_btree.go index d40bafeec..fff430b3e 100644 --- a/container/gtree/gtree_btree.go +++ b/container/gtree/gtree_btree.go @@ -8,10 +8,12 @@ package gtree import ( "bytes" + "context" "fmt" "strings" "github.com/gogf/gf/v2/container/gvar" + "github.com/gogf/gf/v2/internal/intlog" "github.com/gogf/gf/v2/internal/json" "github.com/gogf/gf/v2/internal/rwmutex" "github.com/gogf/gf/v2/util/gconv" @@ -573,8 +575,10 @@ func (tree *BTree) output(buffer *bytes.Buffer, node *BTreeNode, level int, isTa } if e < len(node.Entries) { if _, err := buffer.WriteString(strings.Repeat(" ", level)); err != nil { + intlog.Error(context.TODO(), err) } if _, err := buffer.WriteString(fmt.Sprintf("%v", node.Entries[e].Key) + "\n"); err != nil { + intlog.Error(context.TODO(), err) } } } diff --git a/container/gtype/gtype_bytes.go b/container/gtype/gtype_bytes.go index 8a6834a0c..0f8e4095c 100644 --- a/container/gtype/gtype_bytes.go +++ b/container/gtype/gtype_bytes.go @@ -11,6 +11,7 @@ import ( "encoding/base64" "sync/atomic" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/util/gconv" ) @@ -65,10 +66,13 @@ func (v *Bytes) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. func (v *Bytes) UnmarshalJSON(b []byte) error { - src := make([]byte, base64.StdEncoding.DecodedLen(len(b))) - n, err := base64.StdEncoding.Decode(src, bytes.Trim(b, `"`)) + var ( + src = make([]byte, base64.StdEncoding.DecodedLen(len(b))) + n, err = base64.StdEncoding.Decode(src, bytes.Trim(b, `"`)) + ) if err != nil { - return nil + err = gerror.Wrap(err, `base64.StdEncoding.Decode failed`) + return err } v.Set(src[:n]) return nil diff --git a/container/gtype/gtype_interface.go b/container/gtype/gtype_interface.go index 455608dfc..a9ad7877b 100644 --- a/container/gtype/gtype_interface.go +++ b/container/gtype/gtype_interface.go @@ -59,8 +59,7 @@ func (v *Interface) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. func (v *Interface) UnmarshalJSON(b []byte) error { var i interface{} - err := json.UnmarshalUseNumber(b, &i) - if err != nil { + if err := json.UnmarshalUseNumber(b, &i); err != nil { return err } v.Set(i) diff --git a/container/gvar/gvar.go b/container/gvar/gvar.go index 745919fb9..f5ec03090 100644 --- a/container/gvar/gvar.go +++ b/container/gvar/gvar.go @@ -189,8 +189,7 @@ func (v *Var) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. func (v *Var) UnmarshalJSON(b []byte) error { var i interface{} - err := json.UnmarshalUseNumber(b, &i) - if err != nil { + if err := json.UnmarshalUseNumber(b, &i); err != nil { return err } v.Set(i) diff --git a/crypto/gaes/gaes.go b/crypto/gaes/gaes.go index cc86966ae..8b6e01d21 100644 --- a/crypto/gaes/gaes.go +++ b/crypto/gaes/gaes.go @@ -38,6 +38,7 @@ func Decrypt(cipherText []byte, key []byte, iv ...[]byte) ([]byte, error) { func EncryptCBC(plainText []byte, key []byte, iv ...[]byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `aes.NewCipher failed for key "%s"`, key) return nil, err } blockSize := block.BlockSize() @@ -61,6 +62,7 @@ func EncryptCBC(plainText []byte, key []byte, iv ...[]byte) ([]byte, error) { func DecryptCBC(cipherText []byte, key []byte, iv ...[]byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `aes.NewCipher failed for key "%s"`, key) return nil, err } blockSize := block.BlockSize() @@ -123,6 +125,7 @@ func PKCS5UnPadding(src []byte, blockSize int) ([]byte, error) { func EncryptCFB(plainText []byte, key []byte, padding *int, iv ...[]byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `aes.NewCipher failed for key "%s"`, key) return nil, err } blockSize := block.BlockSize() @@ -145,6 +148,7 @@ func EncryptCFB(plainText []byte, key []byte, padding *int, iv ...[]byte) ([]byt func DecryptCFB(cipherText []byte, key []byte, unPadding int, iv ...[]byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `aes.NewCipher failed for key "%s"`, key) return nil, err } if len(cipherText) < aes.BlockSize { diff --git a/crypto/gdes/gdes.go b/crypto/gdes/gdes.go index 684cb9b8e..9b29ec5ec 100644 --- a/crypto/gdes/gdes.go +++ b/crypto/gdes/gdes.go @@ -29,9 +29,9 @@ func EncryptECB(plainText []byte, key []byte, padding int) ([]byte, error) { } cipherText := make([]byte, len(text)) - block, err := des.NewCipher(key) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `des.NewCipher failed for key "%s"`, key) return nil, err } @@ -48,6 +48,7 @@ func DecryptECB(cipherText []byte, key []byte, padding int) ([]byte, error) { text := make([]byte, len(cipherText)) block, err := des.NewCipher(key) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `des.NewCipher failed for key "%s"`, key) return nil, err } @@ -86,6 +87,7 @@ func EncryptECBTriple(plainText []byte, key []byte, padding int) ([]byte, error) block, err := des.NewTripleDESCipher(newKey) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `des.NewTripleDESCipher failed for key "%s"`, newKey) return nil, err } @@ -115,6 +117,7 @@ func DecryptECBTriple(cipherText []byte, key []byte, padding int) ([]byte, error block, err := des.NewTripleDESCipher(newKey) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `des.NewTripleDESCipher failed for key "%s"`, newKey) return nil, err } @@ -136,11 +139,12 @@ func DecryptECBTriple(cipherText []byte, key []byte, padding int) ([]byte, error func EncryptCBC(plainText []byte, key []byte, iv []byte, padding int) ([]byte, error) { block, err := des.NewCipher(key) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `des.NewCipher failed for key "%s"`, key) return nil, err } if len(iv) != block.BlockSize() { - return nil, gerror.NewCode(gcode.CodeInvalidParameter, "iv length invalid") + return nil, gerror.NewCode(gcode.CodeInvalidParameter, "invalid iv length") } text, err := Padding(plainText, padding) @@ -149,8 +153,8 @@ func EncryptCBC(plainText []byte, key []byte, iv []byte, padding int) ([]byte, e } cipherText := make([]byte, len(text)) - encrypter := cipher.NewCBCEncrypter(block, iv) - encrypter.CryptBlocks(cipherText, text) + encryptor := cipher.NewCBCEncrypter(block, iv) + encryptor.CryptBlocks(cipherText, text) return cipherText, nil } @@ -159,6 +163,7 @@ func EncryptCBC(plainText []byte, key []byte, iv []byte, padding int) ([]byte, e func DecryptCBC(cipherText []byte, key []byte, iv []byte, padding int) ([]byte, error) { block, err := des.NewCipher(key) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `des.NewCipher failed for key "%s"`, key) return nil, err } @@ -194,11 +199,12 @@ func EncryptCBCTriple(plainText []byte, key []byte, iv []byte, padding int) ([]b block, err := des.NewTripleDESCipher(newKey) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `des.NewTripleDESCipher failed for key "%s"`, newKey) return nil, err } if len(iv) != block.BlockSize() { - return nil, gerror.NewCode(gcode.CodeInvalidParameter, "iv length invalid") + return nil, gerror.NewCode(gcode.CodeInvalidParameter, "invalid iv length") } text, err := Padding(plainText, padding) @@ -229,11 +235,12 @@ func DecryptCBCTriple(cipherText []byte, key []byte, iv []byte, padding int) ([] block, err := des.NewTripleDESCipher(newKey) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `des.NewTripleDESCipher failed for key "%s"`, newKey) return nil, err } if len(iv) != block.BlockSize() { - return nil, gerror.NewCode(gcode.CodeInvalidParameter, "iv length invalid") + return nil, gerror.NewCode(gcode.CodeInvalidParameter, "invalid iv length") } text := make([]byte, len(cipherText)) @@ -264,12 +271,14 @@ func Padding(text []byte, padding int) ([]byte, error) { switch padding { case NOPADDING: if len(text)%8 != 0 { - return nil, gerror.NewCode(gcode.CodeInvalidParameter, "text length invalid") + return nil, gerror.NewCode(gcode.CodeInvalidParameter, "invalid text length") } + case PKCS5PADDING: return PaddingPKCS5(text, 8), nil + default: - return nil, gerror.NewCode(gcode.CodeInvalidParameter, "padding type error") + return nil, gerror.NewCodef(gcode.CodeInvalidParameter, `unsupported padding type "%d"`, padding) } return text, nil @@ -279,12 +288,14 @@ func UnPadding(text []byte, padding int) ([]byte, error) { switch padding { case NOPADDING: if len(text)%8 != 0 { - return nil, gerror.NewCode(gcode.CodeInvalidParameter, "text length invalid") + return nil, gerror.NewCode(gcode.CodeInvalidParameter, "invalid text length") } + case PKCS5PADDING: return UnPaddingPKCS5(text), nil + default: - return nil, gerror.NewCode(gcode.CodeInvalidParameter, "padding type error") + return nil, gerror.NewCodef(gcode.CodeInvalidParameter, `unsupported padding type "%d"`, padding) } return text, nil } diff --git a/crypto/gmd5/gmd5.go b/crypto/gmd5/gmd5.go index 40506dffa..5b28bdb80 100644 --- a/crypto/gmd5/gmd5.go +++ b/crypto/gmd5/gmd5.go @@ -13,6 +13,7 @@ import ( "io" "os" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/util/gconv" ) @@ -36,7 +37,8 @@ func MustEncrypt(data interface{}) string { // EncryptBytes encrypts `data` using MD5 algorithms. func EncryptBytes(data []byte) (encrypt string, err error) { h := md5.New() - if _, err = h.Write([]byte(data)); err != nil { + if _, err = h.Write(data); err != nil { + err = gerror.Wrap(err, `hash.Write failed`) return "", err } return fmt.Sprintf("%x", h.Sum(nil)), nil @@ -52,7 +54,7 @@ func MustEncryptBytes(data []byte) string { return result } -// EncryptBytes encrypts string `data` using MD5 algorithms. +// EncryptString encrypts string `data` using MD5 algorithms. func EncryptString(data string) (encrypt string, err error) { return EncryptBytes([]byte(data)) } @@ -71,12 +73,14 @@ func MustEncryptString(data string) string { func EncryptFile(path string) (encrypt string, err error) { f, err := os.Open(path) if err != nil { + err = gerror.Wrapf(err, `os.Open failed for name "%s"`, path) return "", err } defer f.Close() h := md5.New() _, err = io.Copy(h, f) if err != nil { + err = gerror.Wrap(err, `io.Copy failed`) return "", err } return fmt.Sprintf("%x", h.Sum(nil)), nil diff --git a/crypto/gsha1/gsha1.go b/crypto/gsha1/gsha1.go index c461112fb..b2cbbf2c0 100644 --- a/crypto/gsha1/gsha1.go +++ b/crypto/gsha1/gsha1.go @@ -13,6 +13,8 @@ import ( "io" "os" + "github.com/gogf/gf/v2/errors/gcode" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/util/gconv" ) @@ -27,12 +29,14 @@ func Encrypt(v interface{}) string { func EncryptFile(path string) (encrypt string, err error) { f, err := os.Open(path) if err != nil { + err = gerror.Wrapf(err, `os.Open failed for name "%s"`, path) return "", err } defer f.Close() h := sha1.New() _, err = io.Copy(h, f) if err != nil { + err = gerror.Wrap(err, `io.Copy failed`) return "", err } return hex.EncodeToString(h.Sum(nil)), nil diff --git a/database/gdb/gdb.go b/database/gdb/gdb.go index 9763f1426..bec28b4a3 100644 --- a/database/gdb/gdb.go +++ b/database/gdb/gdb.go @@ -274,6 +274,7 @@ const ( sqlTypeExecContext = `DB.ExecContext` sqlTypePrepareContext = `DB.PrepareContext` modelForDaoSuffix = `ForDao` + dbRoleSlave = `slave` ) var ( @@ -400,10 +401,12 @@ func Instance(name ...string) (db DB, err error) { func getConfigNodeByGroup(group string, master bool) (*ConfigNode, error) { if list, ok := configs.config[group]; ok { // Separates master and slave configuration nodes array. - masterList := make(ConfigGroup, 0) - slaveList := make(ConfigGroup, 0) + var ( + masterList = make(ConfigGroup, 0) + slaveList = make(ConfigGroup, 0) + ) for i := 0; i < len(list); i++ { - if list[i].Role == "slave" { + if list[i].Role == dbRoleSlave { slaveList = append(slaveList, list[i]) } else { masterList = append(masterList, list[i]) @@ -513,8 +516,7 @@ func (c *Core) getSqlDb(master bool, schema ...string) (sqlDb *sql.DB, err error } }() - sqlDb, err = c.db.Open(node) - if err != nil { + if sqlDb, err = c.db.Open(node); err != nil { return nil } diff --git a/database/gdb/gdb_core.go b/database/gdb/gdb_core.go index a4e081974..c825d758e 100644 --- a/database/gdb/gdb_core.go +++ b/database/gdb/gdb_core.go @@ -101,6 +101,9 @@ func (c *Core) Close(ctx context.Context) (err error) { for k, v := range m { if db, ok := v.(*sql.DB); ok { err = db.Close() + if err != nil { + err = gerror.WrapCode(gcode.CodeDbOperationError, err, `db.Close failed`) + } intlog.Printf(ctx, `close link: %s, err: %v`, k, err) if err != nil { return @@ -283,7 +286,10 @@ func (c *Core) PingMaster() error { if master, err := c.db.Master(); err != nil { return err } else { - return master.Ping() + if err = master.Ping(); err != nil { + err = gerror.WrapCode(gcode.CodeDbOperationError, err, `master.Ping failed`) + } + return err } } @@ -292,7 +298,10 @@ func (c *Core) PingSlave() error { if slave, err := c.db.Slave(); err != nil { return err } else { - return slave.Ping() + if err = slave.Ping(); err != nil { + err = gerror.WrapCode(gcode.CodeDbOperationError, err, `slave.Ping failed`) + } + return err } } @@ -425,20 +434,25 @@ func (c *Core) DoInsert(ctx context.Context, link Link, table string, list List, valueHolder = append(valueHolder, "("+gstr.Join(values, ",")+")") // Batch package checks: It meets the batch number, or it is the last element. if len(valueHolder) == option.BatchCount || (i == listLength-1 && len(valueHolder) > 0) { - r, err := c.db.DoExec(ctx, link, fmt.Sprintf( + var ( + stdSqlResult sql.Result + affectedRows int64 + ) + stdSqlResult, err = c.db.DoExec(ctx, link, fmt.Sprintf( "%s INTO %s(%s) VALUES%s %s", operation, c.QuotePrefixTableName(table), keysStr, gstr.Join(valueHolder, ","), onDuplicateStr, ), params...) if err != nil { - return r, err + return stdSqlResult, err } - if n, err := r.RowsAffected(); err != nil { - return r, err + if affectedRows, err = stdSqlResult.RowsAffected(); err != nil { + err = gerror.WrapCode(gcode.CodeDbOperationError, err, `sql.Result.RowsAffected failed`) + return stdSqlResult, err } else { - batchResult.result = r - batchResult.affected += n + batchResult.result = stdSqlResult + batchResult.affected += affectedRows } params = params[:0] valueHolder = valueHolder[:0] @@ -531,8 +545,8 @@ func (c *Core) DoUpdate(ctx context.Context, link Link, table string, data inter dataMap = ConvertDataForTableRecord(data) counterHandler = func(column string, counter Counter) { if counter.Value != 0 { + column = c.QuoteWord(column) var ( - column = c.QuoteWord(column) columnRef = c.QuoteWord(counter.Field) columnVal = counter.Value operator = "+" diff --git a/database/gdb/gdb_core_structure.go b/database/gdb/gdb_core_structure.go index 6fb33872e..5d97351da 100644 --- a/database/gdb/gdb_core_structure.go +++ b/database/gdb/gdb_core_structure.go @@ -26,9 +26,9 @@ func (c *Core) convertFieldValueToLocalValue(fieldValue interface{}, fieldType s if fieldType == "" { return fieldValue } - t, _ := gregex.ReplaceString(`\(.+\)`, "", fieldType) - t = strings.ToLower(t) - switch t { + typeName, _ := gregex.ReplaceString(`\(.+\)`, "", fieldType) + typeName = strings.ToLower(typeName) + switch typeName { case "binary", "varbinary", @@ -107,22 +107,22 @@ func (c *Core) convertFieldValueToLocalValue(fieldValue interface{}, fieldType s default: // Auto-detect field type, using key match. switch { - case strings.Contains(t, "text") || strings.Contains(t, "char") || strings.Contains(t, "character"): + case strings.Contains(typeName, "text") || strings.Contains(typeName, "char") || strings.Contains(typeName, "character"): return gconv.String(fieldValue) - case strings.Contains(t, "float") || strings.Contains(t, "double") || strings.Contains(t, "numeric"): + case strings.Contains(typeName, "float") || strings.Contains(typeName, "double") || strings.Contains(typeName, "numeric"): return gconv.Float64(gconv.String(fieldValue)) - case strings.Contains(t, "bool"): + case strings.Contains(typeName, "bool"): return gconv.Bool(gconv.String(fieldValue)) - case strings.Contains(t, "binary") || strings.Contains(t, "blob"): + case strings.Contains(typeName, "binary") || strings.Contains(typeName, "blob"): return fieldValue - case strings.Contains(t, "int"): + case strings.Contains(typeName, "int"): return gconv.Int(gconv.String(fieldValue)) - case strings.Contains(t, "time"): + case strings.Contains(typeName, "time"): s := gconv.String(fieldValue) t, err := gtime.StrToTime(s) if err != nil { @@ -130,7 +130,7 @@ func (c *Core) convertFieldValueToLocalValue(fieldValue interface{}, fieldType s } return t.String() - case strings.Contains(t, "date"): + case strings.Contains(typeName, "date"): s := gconv.String(fieldValue) t, err := gtime.StrToTime(s) if err != nil { diff --git a/database/gdb/gdb_core_transaction.go b/database/gdb/gdb_core_transaction.go index 755803585..7005290f9 100644 --- a/database/gdb/gdb_core_transaction.go +++ b/database/gdb/gdb_core_transaction.go @@ -118,7 +118,7 @@ func (c *Core) Transaction(ctx context.Context, f func(ctx context.Context, tx * if v, ok := exception.(error); ok && gerror.HasStack(v) { err = v } else { - err = gerror.NewCodef(gcode.CodeInternalError, "%+v", exception) + err = gerror.Newf("%+v", exception) } } } @@ -143,11 +143,11 @@ func WithTX(ctx context.Context, tx *TX) context.Context { } // Check repeat injection from given. group := tx.db.GetGroup() - if tx := TXFromCtx(ctx, group); tx != nil && tx.db.GetGroup() == group { + if ctxTx := TXFromCtx(ctx, group); ctxTx != nil && ctxTx.db.GetGroup() == group { return ctx } dbCtx := tx.db.GetCtx() - if tx := TXFromCtx(dbCtx, group); tx != nil && tx.db.GetGroup() == group { + if ctxTx := TXFromCtx(dbCtx, group); ctxTx != nil && ctxTx.db.GetGroup() == group { return dbCtx } // Inject transaction object and id into context. @@ -215,6 +215,9 @@ func (tx *TX) Commit() error { IsTransaction: true, } ) + if err != nil { + err = gerror.WrapCode(gcode.CodeDbOperationError, err, `tx.Commit failed`) + } tx.isClosed = true tx.db.GetCore().addSqlToTracing(tx.ctx, sqlObj) if tx.db.GetDebug() { @@ -249,6 +252,9 @@ func (tx *TX) Rollback() error { IsTransaction: true, } ) + if err != nil { + err = gerror.WrapCode(gcode.CodeDbOperationError, err, `tx.Rollback failed`) + } tx.isClosed = true tx.db.GetCore().addSqlToTracing(tx.ctx, sqlObj) if tx.db.GetDebug() { @@ -312,7 +318,7 @@ func (tx *TX) Transaction(ctx context.Context, f func(ctx context.Context, tx *T if v, ok := exception.(error); ok && gerror.HasStack(v) { err = v } else { - err = gerror.NewCodef(gcode.CodeInternalError, "%+v", exception) + err = gerror.Newf("%+v", exception) } } } diff --git a/database/gdb/gdb_driver_mssql.go b/database/gdb/gdb_driver_mssql.go index 74a5f6566..85adf7094 100644 --- a/database/gdb/gdb_driver_mssql.go +++ b/database/gdb/gdb_driver_mssql.go @@ -39,8 +39,11 @@ func (d *DriverMssql) New(core *Core, node *ConfigNode) (DB, error) { } // Open creates and returns an underlying sql.DB object for mssql. -func (d *DriverMssql) Open(config *ConfigNode) (*sql.DB, error) { - source := "" +func (d *DriverMssql) Open(config *ConfigNode) (db *sql.DB, err error) { + var ( + source string + driver = "sqlserver" + ) if config.Link != "" { source = config.Link } else { @@ -50,11 +53,14 @@ func (d *DriverMssql) Open(config *ConfigNode) (*sql.DB, error) { ) } intlog.Printf(d.GetCtx(), "Open: %s", source) - if db, err := sql.Open("sqlserver", source); err == nil { - return db, nil - } else { + if db, err = sql.Open(driver, source); err != nil { + err = gerror.WrapCodef( + gcode.CodeDbOperationError, err, + `sql.Open failed for driver "%s" by source "%s"`, driver, source, + ) return nil, err } + return } // FilteredLink retrieves and returns filtered `linkInfo` that can be using for diff --git a/database/gdb/gdb_driver_mysql.go b/database/gdb/gdb_driver_mysql.go index 758f43239..eafa9210d 100644 --- a/database/gdb/gdb_driver_mysql.go +++ b/database/gdb/gdb_driver_mysql.go @@ -36,8 +36,11 @@ func (d *DriverMysql) New(core *Core, node *ConfigNode) (DB, error) { // Open creates and returns an underlying sql.DB object for mysql. // Note that it converts time.Time argument to local timezone in default. -func (d *DriverMysql) Open(config *ConfigNode) (*sql.DB, error) { - var source string +func (d *DriverMysql) Open(config *ConfigNode) (db *sql.DB, err error) { + var ( + source string + driver = "mysql" + ) if config.Link != "" { source = config.Link // Custom changing the schema in runtime. @@ -54,11 +57,14 @@ func (d *DriverMysql) Open(config *ConfigNode) (*sql.DB, error) { } } intlog.Printf(d.GetCtx(), "Open: %s", source) - if db, err := sql.Open("mysql", source); err == nil { - return db, nil - } else { + if db, err = sql.Open(driver, source); err != nil { + err = gerror.WrapCodef( + gcode.CodeDbOperationError, err, + `sql.Open failed for driver "%s" by source "%s"`, driver, source, + ) return nil, err } + return } // FilteredLink retrieves and returns filtered `linkInfo` that can be using for diff --git a/database/gdb/gdb_driver_oracle.go b/database/gdb/gdb_driver_oracle.go index 872b59e8c..4ee244aa0 100644 --- a/database/gdb/gdb_driver_oracle.go +++ b/database/gdb/gdb_driver_oracle.go @@ -42,8 +42,11 @@ func (d *DriverOracle) New(core *Core, node *ConfigNode) (DB, error) { } // Open creates and returns a underlying sql.DB object for oracle. -func (d *DriverOracle) Open(config *ConfigNode) (*sql.DB, error) { - var source string +func (d *DriverOracle) Open(config *ConfigNode) (db *sql.DB, err error) { + var ( + source string + driver = "oci8" + ) if config.Link != "" { source = config.Link } else { @@ -53,11 +56,14 @@ func (d *DriverOracle) Open(config *ConfigNode) (*sql.DB, error) { ) } intlog.Printf(d.GetCtx(), "Open: %s", source) - if db, err := sql.Open("oci8", source); err == nil { - return db, nil - } else { + if db, err = sql.Open(driver, source); err != nil { + err = gerror.WrapCodef( + gcode.CodeDbOperationError, err, + `sql.Open failed for driver "%s" by source "%s"`, driver, source, + ) return nil, err } + return } // FilteredLink retrieves and returns filtered `linkInfo` that can be using for diff --git a/database/gdb/gdb_driver_pgsql.go b/database/gdb/gdb_driver_pgsql.go index 60ce1e266..b1ad84bd7 100644 --- a/database/gdb/gdb_driver_pgsql.go +++ b/database/gdb/gdb_driver_pgsql.go @@ -38,8 +38,11 @@ func (d *DriverPgsql) New(core *Core, node *ConfigNode) (DB, error) { } // Open creates and returns a underlying sql.DB object for pgsql. -func (d *DriverPgsql) Open(config *ConfigNode) (*sql.DB, error) { - var source string +func (d *DriverPgsql) Open(config *ConfigNode) (db *sql.DB, err error) { + var ( + source string + driver = "postgres" + ) if config.Link != "" { source = config.Link } else { @@ -52,11 +55,14 @@ func (d *DriverPgsql) Open(config *ConfigNode) (*sql.DB, error) { } } intlog.Printf(d.GetCtx(), "Open: %s", source) - if db, err := sql.Open("postgres", source); err == nil { - return db, nil - } else { + if db, err = sql.Open(driver, source); err != nil { + err = gerror.WrapCodef( + gcode.CodeDbOperationError, err, + `sql.Open failed for driver "%s" by source "%s"`, driver, source, + ) return nil, err } + return } // FilteredLink retrieves and returns filtered `linkInfo` that can be using for diff --git a/database/gdb/gdb_driver_sqlite.go b/database/gdb/gdb_driver_sqlite.go index 155270dca..7f5ed072e 100644 --- a/database/gdb/gdb_driver_sqlite.go +++ b/database/gdb/gdb_driver_sqlite.go @@ -37,8 +37,11 @@ func (d *DriverSqlite) New(core *Core, node *ConfigNode) (DB, error) { } // Open creates and returns a underlying sql.DB object for sqlite. -func (d *DriverSqlite) Open(config *ConfigNode) (*sql.DB, error) { - var source string +func (d *DriverSqlite) Open(config *ConfigNode) (db *sql.DB, err error) { + var ( + source string + driver = "sqlite3" + ) if config.Link != "" { source = config.Link } else { @@ -49,11 +52,14 @@ func (d *DriverSqlite) Open(config *ConfigNode) (*sql.DB, error) { source = absolutePath } intlog.Printf(d.GetCtx(), "Open: %s", source) - if db, err := sql.Open("sqlite3", source); err == nil { - return db, nil - } else { + if db, err = sql.Open(driver, source); err != nil { + err = gerror.WrapCodef( + gcode.CodeDbOperationError, err, + `sql.Open failed for driver "%s" by source "%s"`, driver, source, + ) return nil, err } + return } // FilteredLink retrieves and returns filtered `linkInfo` that can be using for diff --git a/database/gdb/gdb_result.go b/database/gdb/gdb_result.go index 63134bb09..3744bdf6a 100644 --- a/database/gdb/gdb_result.go +++ b/database/gdb/gdb_result.go @@ -6,7 +6,11 @@ package gdb -import "database/sql" +import ( + "database/sql" + + "github.com/gogf/gf/v2/errors/gerror" +) // SqlResult is execution result for sql operations. // It also supports batch operation result for rowsAffected. @@ -19,6 +23,7 @@ type SqlResult struct { func (r *SqlResult) MustGetAffected() int64 { rows, err := r.RowsAffected() if err != nil { + err = gerror.Wrap(err, `sql.Result.RowsAffected failed`) panic(err) } return rows @@ -28,6 +33,7 @@ func (r *SqlResult) MustGetAffected() int64 { func (r *SqlResult) MustGetInsertId() int64 { id, err := r.LastInsertId() if err != nil { + err = gerror.Wrap(err, `sql.Result.LastInsertId failed`) panic(err) } return id @@ -36,7 +42,7 @@ func (r *SqlResult) MustGetInsertId() int64 { // RowsAffected returns the number of rows affected by an // update, insert, or delete. Not every database or database // driver may support this. -// Also See sql.Result. +// Also, See sql.Result. func (r *SqlResult) RowsAffected() (int64, error) { if r.affected > 0 { return r.affected, nil @@ -48,11 +54,11 @@ func (r *SqlResult) RowsAffected() (int64, error) { } // LastInsertId returns the integer generated by the database -// in response to a command. Typically this will be from an +// in response to a command. Typically, this will be from an // "auto increment" column when inserting a new row. Not all // databases support this feature, and the syntax of such // statements varies. -// Also See sql.Result. +// Also, See sql.Result. func (r *SqlResult) LastInsertId() (int64, error) { if r.result == nil { return 0, nil diff --git a/debug/gdebug/gdebug_version.go b/debug/gdebug/gdebug_version.go index 55fb56393..54c11215d 100644 --- a/debug/gdebug/gdebug_version.go +++ b/debug/gdebug/gdebug_version.go @@ -7,11 +7,15 @@ package gdebug import ( + "crypto/md5" + "fmt" + "io" "io/ioutil" + "os" "strconv" - "github.com/gogf/gf/v2/crypto/gmd5" "github.com/gogf/gf/v2/encoding/ghash" + "github.com/gogf/gf/v2/errors/gerror" ) // BinVersion returns the version of current running binary. @@ -31,7 +35,24 @@ func BinVersion() string { // It uses MD5 algorithm to calculate the unique version of the binary. func BinVersionMd5() string { if binaryVersionMd5 == "" { - binaryVersionMd5, _ = gmd5.EncryptFile(selfPath) + binaryVersionMd5, _ = md5File(selfPath) } return binaryVersionMd5 } + +// md5File encrypts file content of `path` using MD5 algorithms. +func md5File(path string) (encrypt string, err error) { + f, err := os.Open(path) + if err != nil { + err = gerror.Wrapf(err, `os.Open failed for name "%s"`, path) + return "", err + } + defer f.Close() + h := md5.New() + _, err = io.Copy(h, f) + if err != nil { + err = gerror.Wrap(err, `io.Copy failed`) + return "", err + } + return fmt.Sprintf("%x", h.Sum(nil)), nil +} diff --git a/encoding/gbase64/gbase64.go b/encoding/gbase64/gbase64.go index 6308947f1..566d68c5a 100644 --- a/encoding/gbase64/gbase64.go +++ b/encoding/gbase64/gbase64.go @@ -10,6 +10,8 @@ package gbase64 import ( "encoding/base64" "io/ioutil" + + "github.com/gogf/gf/v2/errors/gerror" ) // Encode encodes bytes with BASE64 algorithm. @@ -33,6 +35,7 @@ func EncodeToString(src []byte) string { func EncodeFile(path string) ([]byte, error) { content, err := ioutil.ReadFile(path) if err != nil { + err = gerror.Wrapf(err, `ioutil.ReadFile failed for filename "%s"`, path) return nil, err } return Encode(content), nil @@ -69,8 +72,13 @@ func MustEncodeFileToString(path string) string { // Decode decodes bytes with BASE64 algorithm. func Decode(data []byte) ([]byte, error) { - src := make([]byte, base64.StdEncoding.DecodedLen(len(data))) - n, err := base64.StdEncoding.Decode(src, data) + var ( + src = make([]byte, base64.StdEncoding.DecodedLen(len(data))) + n, err = base64.StdEncoding.Decode(src, data) + ) + if err != nil { + err = gerror.Wrap(err, `base64.StdEncoding.Decode failed`) + } return src[:n], err } diff --git a/encoding/gbinary/gbinary_be.go b/encoding/gbinary/gbinary_be.go index 2ff9b2e64..45ac80b30 100644 --- a/encoding/gbinary/gbinary_be.go +++ b/encoding/gbinary/gbinary_be.go @@ -8,9 +8,13 @@ package gbinary import ( "bytes" + "context" "encoding/binary" "fmt" "math" + + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/internal/intlog" ) // BeEncode encodes one or multiple `values` into bytes using BigEndian. @@ -59,6 +63,7 @@ func BeEncode(values ...interface{}) []byte { buf.Write(BeEncodeFloat64(value)) default: if err := binary.Write(buf, binary.BigEndian, value); err != nil { + intlog.Error(context.TODO(), err) buf.Write(BeEncodeString(fmt.Sprintf("%v", value))) } } @@ -66,8 +71,6 @@ func BeEncode(values ...interface{}) []byte { return buf.Bytes() } -// 将变量转换为二进制[]byte,并指定固定的[]byte长度返回,长度单位为字节(byte); -// 如果转换的二进制长度超过指定长度,那么进行截断处理 func BeEncodeByLength(length int, values ...interface{}) []byte { b := BeEncode(values...) if len(b) < length { @@ -78,13 +81,14 @@ func BeEncodeByLength(length int, values ...interface{}) []byte { return b } -// 整形二进制解包,注意第二个及其后参数为字长确定的整形变量的指针地址,以便确定解析的[]byte长度, -// 例如:int8/16/32/64、uint8/16/32/64、float32/64等等 func BeDecode(b []byte, values ...interface{}) error { - buf := bytes.NewBuffer(b) + var ( + err error + buf = bytes.NewBuffer(b) + ) for i := 0; i < len(values); i++ { - err := binary.Read(buf, binary.BigEndian, values[i]) - if err != nil { + if err = binary.Read(buf, binary.BigEndian, values[i]); err != nil { + err = gerror.Wrap(err, `binary.Read failed`) return err } } @@ -107,7 +111,6 @@ func BeEncodeBool(b bool) []byte { } } -// 自动识别int类型长度,转换为[]byte func BeEncodeInt(i int) []byte { if i <= math.MaxInt8 { return BeEncodeInt8(int8(i)) @@ -120,7 +123,6 @@ func BeEncodeInt(i int) []byte { } } -// 自动识别uint类型长度,转换为[]byte func BeEncodeUint(i uint) []byte { if i <= math.MaxUint8 { return BeEncodeUint8(uint8(i)) @@ -191,8 +193,6 @@ func BeEncodeFloat64(f float64) []byte { return b } -// 将二进制解析为int类型,根据[]byte的长度进行自动转换. -// 注意内部使用的是uint*,使用int会造成位丢失。 func BeDecodeToInt(b []byte) int { if len(b) < 2 { return int(BeDecodeToUint8(b)) @@ -205,7 +205,6 @@ func BeDecodeToInt(b []byte) int { } } -// 将二进制解析为uint类型,根据[]byte的长度进行自动转换 func BeDecodeToUint(b []byte) uint { if len(b) < 2 { return uint(BeDecodeToUint8(b)) @@ -218,7 +217,6 @@ func BeDecodeToUint(b []byte) uint { } } -// 将二进制解析为bool类型,识别标准是判断二进制中数值是否都为0,或者为空。 func BeDecodeToBool(b []byte) bool { if len(b) == 0 { return false @@ -230,11 +228,17 @@ func BeDecodeToBool(b []byte) bool { } func BeDecodeToInt8(b []byte) int8 { + if len(b) == 0 { + panic(`empty slice given`) + } return int8(b[0]) } func BeDecodeToUint8(b []byte) uint8 { - return uint8(b[0]) + if len(b) == 0 { + panic(`empty slice given`) + } + return b[0] } func BeDecodeToInt16(b []byte) int16 { diff --git a/encoding/gbinary/gbinary_le.go b/encoding/gbinary/gbinary_le.go index 63e7cbe0f..6cce14179 100644 --- a/encoding/gbinary/gbinary_le.go +++ b/encoding/gbinary/gbinary_le.go @@ -8,9 +8,13 @@ package gbinary import ( "bytes" + "context" "encoding/binary" "fmt" "math" + + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/internal/intlog" ) // LeEncode encodes one or multiple `values` into bytes using LittleEndian. @@ -59,6 +63,7 @@ func LeEncode(values ...interface{}) []byte { buf.Write(LeEncodeFloat64(value)) default: if err := binary.Write(buf, binary.LittleEndian, value); err != nil { + intlog.Error(context.TODO(), err) buf.Write(LeEncodeString(fmt.Sprintf("%v", value))) } } @@ -66,8 +71,6 @@ func LeEncode(values ...interface{}) []byte { return buf.Bytes() } -// 将变量转换为二进制[]byte,并指定固定的[]byte长度返回,长度单位为字节(byte); -// 如果转换的二进制长度超过指定长度,那么进行截断处理 func LeEncodeByLength(length int, values ...interface{}) []byte { b := LeEncode(values...) if len(b) < length { @@ -78,13 +81,14 @@ func LeEncodeByLength(length int, values ...interface{}) []byte { return b } -// 整形二进制解包,注意第二个及其后参数为字长确定的整形变量的指针地址,以便确定解析的[]byte长度, -// 例如:int8/16/32/64、uint8/16/32/64、float32/64等等 func LeDecode(b []byte, values ...interface{}) error { - buf := bytes.NewBuffer(b) + var ( + err error + buf = bytes.NewBuffer(b) + ) for i := 0; i < len(values); i++ { - err := binary.Read(buf, binary.LittleEndian, values[i]) - if err != nil { + if err = binary.Read(buf, binary.LittleEndian, values[i]); err != nil { + err = gerror.Wrap(err, `binary.Read failed`) return err } } @@ -107,7 +111,6 @@ func LeEncodeBool(b bool) []byte { } } -// 自动识别int类型长度,转换为[]byte func LeEncodeInt(i int) []byte { if i <= math.MaxInt8 { return EncodeInt8(int8(i)) @@ -120,7 +123,6 @@ func LeEncodeInt(i int) []byte { } } -// 自动识别uint类型长度,转换为[]byte func LeEncodeUint(i uint) []byte { if i <= math.MaxUint8 { return EncodeUint8(uint8(i)) @@ -191,8 +193,6 @@ func LeEncodeFloat64(f float64) []byte { return b } -// 将二进制解析为int类型,根据[]byte的长度进行自动转换. -// 注意内部使用的是uint*,使用int会造成位丢失。 func LeDecodeToInt(b []byte) int { if len(b) < 2 { return int(LeDecodeToUint8(b)) @@ -205,7 +205,6 @@ func LeDecodeToInt(b []byte) int { } } -// 将二进制解析为uint类型,根据[]byte的长度进行自动转换 func LeDecodeToUint(b []byte) uint { if len(b) < 2 { return uint(LeDecodeToUint8(b)) @@ -218,7 +217,6 @@ func LeDecodeToUint(b []byte) uint { } } -// 将二进制解析为bool类型,识别标准是判断二进制中数值是否都为0,或者为空。 func LeDecodeToBool(b []byte) bool { if len(b) == 0 { return false @@ -230,11 +228,17 @@ func LeDecodeToBool(b []byte) bool { } func LeDecodeToInt8(b []byte) int8 { + if len(b) == 0 { + panic(`empty slice given`) + } return int8(b[0]) } func LeDecodeToUint8(b []byte) uint8 { - return uint8(b[0]) + if len(b) == 0 { + panic(`empty slice given`) + } + return b[0] } func LeDecodeToInt16(b []byte) int16 { @@ -269,8 +273,10 @@ func LeDecodeToFloat64(b []byte) float64 { return math.Float64frombits(binary.LittleEndian.Uint64(LeFillUpSize(b, 8))) } -// 当b位数不够时,进行高位补0。 -// 注意这里为了不影响原有输入参数,是采用的值复制设计。 +// LeFillUpSize fills up the bytes `b` to given length `l` using LittleEndian. +// +// Note that it creates a new bytes slice by copying the original one to avoid changing +// the original parameter bytes. func LeFillUpSize(b []byte, l int) []byte { if len(b) >= l { return b[:l] diff --git a/encoding/gcharset/gcharset.go b/encoding/gcharset/gcharset.go index bd283bc56..021879128 100644 --- a/encoding/gcharset/gcharset.go +++ b/encoding/gcharset/gcharset.go @@ -63,11 +63,11 @@ func Convert(dstCharset string, srcCharset string, src string) (dst string, err transform.NewReader(bytes.NewReader([]byte(src)), e.NewDecoder()), ) if err != nil { - return "", gerror.WrapCodef(gcode.CodeInternalError, err, "%s to utf8 failed", srcCharset) + return "", gerror.Wrapf(err, `convert string "%s" to utf8 failed`, srcCharset) } src = string(tmp) } else { - return dst, gerror.NewCodef(gcode.CodeInvalidParameter, "unsupported srcCharset: %s", srcCharset) + return dst, gerror.NewCodef(gcode.CodeInvalidParameter, `unsupported srcCharset "%s"`, srcCharset) } } // Do the converting from UTF-8 to `dstCharset`. @@ -77,11 +77,11 @@ func Convert(dstCharset string, srcCharset string, src string) (dst string, err transform.NewReader(bytes.NewReader([]byte(src)), e.NewEncoder()), ) if err != nil { - return "", gerror.WrapCodef(gcode.CodeInternalError, err, "utf to %s failed", dstCharset) + return "", gerror.Wrapf(err, `convert string from utf8 to "%s" failed`, dstCharset) } dst = string(tmp) } else { - return dst, gerror.NewCodef(gcode.CodeInvalidParameter, "unsupported dstCharset: %s", dstCharset) + return dst, gerror.NewCodef(gcode.CodeInvalidParameter, `unsupported dstCharset "%s"`, dstCharset) } } else { dst = src diff --git a/encoding/gcompress/gcompress_gzip.go b/encoding/gcompress/gcompress_gzip.go index 0ce292534..983aaa11e 100644 --- a/encoding/gcompress/gcompress_gzip.go +++ b/encoding/gcompress/gcompress_gzip.go @@ -11,6 +11,7 @@ import ( "compress/gzip" "io" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/os/gfile" ) @@ -28,15 +29,18 @@ func Gzip(data []byte, level ...int) ([]byte, error) { if len(level) > 0 { writer, err = gzip.NewWriterLevel(&buf, level[0]) if err != nil { + err = gerror.Wrap(err, `gzip.NewWriterLevel failed`) return nil, err } } else { writer = gzip.NewWriter(&buf) } if _, err = writer.Write(data); err != nil { + err = gerror.Wrap(err, `writer.Write failed`) return nil, err } if err = writer.Close(); err != nil { + err = gerror.Wrap(err, `writer.Close failed`) return nil, err } return buf.Bytes(), nil @@ -62,6 +66,7 @@ func GzipFile(src, dst string, level ...int) error { if len(level) > 0 { writer, err = gzip.NewWriterLevel(dstFile, level[0]) if err != nil { + err = gerror.Wrap(err, `gzip.NewWriterLevel failed`) return err } } else { @@ -71,6 +76,7 @@ func GzipFile(src, dst string, level ...int) error { _, err = io.Copy(writer, srcFile) if err != nil { + err = gerror.Wrap(err, `io.Copy failed`) return err } return nil @@ -81,12 +87,15 @@ func UnGzip(data []byte) ([]byte, error) { var buf bytes.Buffer reader, err := gzip.NewReader(bytes.NewReader(data)) if err != nil { + err = gerror.Wrap(err, `gzip.NewReader failed`) return nil, err } if _, err = io.Copy(&buf, reader); err != nil { + err = gerror.Wrap(err, `io.Copy failed`) return nil, err } if err = reader.Close(); err != nil { + err = gerror.Wrap(err, `reader.Close failed`) return buf.Bytes(), err } return buf.Bytes(), nil @@ -107,11 +116,13 @@ func UnGzipFile(src, dst string) error { reader, err := gzip.NewReader(srcFile) if err != nil { + err = gerror.Wrap(err, `gzip.NewReader failed`) return err } defer reader.Close() if _, err = io.Copy(dstFile, reader); err != nil { + err = gerror.Wrap(err, `io.Copy failed`) return err } return nil diff --git a/encoding/gcompress/gcompress_zip.go b/encoding/gcompress/gcompress_zip.go index a9ee32bf0..cdeae621c 100644 --- a/encoding/gcompress/gcompress_zip.go +++ b/encoding/gcompress/gcompress_zip.go @@ -15,6 +15,7 @@ import ( "path/filepath" "strings" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/internal/intlog" "github.com/gogf/gf/v2/os/gfile" "github.com/gogf/gf/v2/text/gstr" @@ -28,6 +29,7 @@ import ( func ZipPath(paths, dest string, prefix ...string) error { writer, err := os.Create(dest) if err != nil { + err = gerror.Wrapf(err, `os.Create failed for name "%s"`, dest) return err } defer writer.Close() @@ -35,7 +37,7 @@ func ZipPath(paths, dest string, prefix ...string) error { defer zipWriter.Close() for _, path := range strings.Split(paths, ",") { path = strings.TrimSpace(path) - if err := doZipPathWriter(path, gfile.RealPath(dest), zipWriter, prefix...); err != nil { + if err = doZipPathWriter(path, gfile.RealPath(dest), zipWriter, prefix...); err != nil { return err } } @@ -64,8 +66,10 @@ func ZipPathWriter(paths string, writer io.Writer, prefix ...string) error { // commonly the destination zip file path. // The unnecessary parameter `prefix` indicates the path prefix for zip file. func doZipPathWriter(path string, exclude string, zipWriter *zip.Writer, prefix ...string) error { - var err error - var files []string + var ( + err error + files []string + ) path, err = gfile.Search(path) if err != nil { return err @@ -101,8 +105,7 @@ func doZipPathWriter(path string, exclude string, zipWriter *zip.Writer, prefix if dir == "." { dir = "" } - err := zipFile(file, headerPrefix+dir, zipWriter) - if err != nil { + if err = zipFile(file, headerPrefix+dir, zipWriter); err != nil { return err } } @@ -117,6 +120,7 @@ func doZipPathWriter(path string, exclude string, zipWriter *zip.Writer, prefix func UnZipFile(archive, dest string, path ...string) error { readerCloser, err := zip.OpenReader(archive) if err != nil { + err = gerror.Wrapf(err, `zip.OpenReader failed for name "%s"`, dest) return err } defer readerCloser.Close() @@ -131,6 +135,7 @@ func UnZipFile(archive, dest string, path ...string) error { func UnZipContent(data []byte, dest string, path ...string) error { reader, err := zip.NewReader(bytes.NewReader(data), int64(len(data))) if err != nil { + err = gerror.Wrapf(err, `zip.NewReader failed`) return err } return unZipFileWithReader(reader, dest, path...) @@ -144,7 +149,11 @@ func unZipFileWithReader(reader *zip.Reader, dest string, path ...string) error if err := os.MkdirAll(dest, 0755); err != nil { return err } - name := "" + var ( + name string + dstPath string + dstDir string + ) for _, file := range reader.File { name = gstr.Replace(file.Name, `\`, `/`) name = gstr.Trim(name, "/") @@ -154,35 +163,45 @@ func unZipFileWithReader(reader *zip.Reader, dest string, path ...string) error } name = name[len(prefix):] } - path := filepath.Join(dest, name) + dstPath = filepath.Join(dest, name) if file.FileInfo().IsDir() { - os.MkdirAll(path, file.Mode()) + _ = os.MkdirAll(dstPath, file.Mode()) continue } - dir := filepath.Dir(path) - if len(dir) > 0 { - if _, err := os.Stat(dir); os.IsNotExist(err) { - err = os.MkdirAll(dir, 0755) - if err != nil { + dstDir = filepath.Dir(dstPath) + if len(dstDir) > 0 { + if _, err := os.Stat(dstDir); os.IsNotExist(err) { + if err = os.MkdirAll(dstDir, 0755); err != nil { + err = gerror.Wrapf(err, `os.MkdirAll failed for path "%s"`, dstDir) return err } } } fileReader, err := file.Open() if err != nil { + err = gerror.Wrapf(err, `file.Open failed`) return err } - defer fileReader.Close() + // The fileReader is closed in function doCopyForUnZipFileWithReader. + if err = doCopyForUnZipFileWithReader(file, fileReader, dstPath); err != nil { + return err + } + } + return nil +} - targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode()) - if err != nil { - return err - } - defer targetFile.Close() +func doCopyForUnZipFileWithReader(file *zip.File, fileReader io.ReadCloser, dstPath string) error { + defer fileReader.Close() + targetFile, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode()) + if err != nil { + err = gerror.Wrapf(err, `os.OpenFile failed for name "%s"`, dstPath) + return err + } + defer targetFile.Close() - if _, err := io.Copy(targetFile, fileReader); err != nil { - return err - } + if _, err = io.Copy(targetFile, fileReader); err != nil { + err = gerror.Wrapf(err, `io.Copy failed from "%s" to "%s"`, file.Name, dstPath) + return err } return nil } @@ -192,12 +211,14 @@ func unZipFileWithReader(reader *zip.Reader, dest string, path ...string) error func zipFile(path string, prefix string, zw *zip.Writer) error { file, err := os.Open(path) if err != nil { + err = gerror.Wrapf(err, `os.Open failed for name "%s"`, path) return nil } defer file.Close() info, err := file.Stat() if err != nil { + err = gerror.Wrapf(err, `file.Stat failed for name "%s"`, path) return err } @@ -214,10 +235,12 @@ func zipFile(path string, prefix string, zw *zip.Writer) error { writer, err := zw.CreateHeader(header) if err != nil { + err = gerror.Wrapf(err, `zip.Writer.CreateHeader failed for header "%#v"`, header) return err } if !info.IsDir() { if _, err = io.Copy(writer, file); err != nil { + err = gerror.Wrapf(err, `io.Copy failed from "%s" to "%s"`, path, header.Name) return err } } @@ -227,6 +250,7 @@ func zipFile(path string, prefix string, zw *zip.Writer) error { func createFileHeader(info os.FileInfo, prefix string) (*zip.FileHeader, error) { header, err := zip.FileInfoHeader(info) if err != nil { + err = gerror.Wrapf(err, `zip.FileInfoHeader failed for info "%#v"`, info) return nil, err } diff --git a/encoding/gcompress/gcompress_zlib.go b/encoding/gcompress/gcompress_zlib.go index f0dc74660..c45b3d2bd 100644 --- a/encoding/gcompress/gcompress_zlib.go +++ b/encoding/gcompress/gcompress_zlib.go @@ -11,6 +11,8 @@ import ( "bytes" "compress/zlib" "io" + + "github.com/gogf/gf/v2/errors/gerror" ) // Zlib compresses `data` with zlib algorithm. @@ -18,13 +20,18 @@ func Zlib(data []byte) ([]byte, error) { if data == nil || len(data) < 13 { return data, nil } - var in bytes.Buffer - var err error - w := zlib.NewWriter(&in) - if _, err = w.Write(data); err != nil { + var ( + err error + in bytes.Buffer + writer = zlib.NewWriter(&in) + ) + + if _, err = writer.Write(data); err != nil { + err = gerror.Wrapf(err, `zlib.Writer.Write failed`) return nil, err } - if err = w.Close(); err != nil { + if err = writer.Close(); err != nil { + err = gerror.Wrapf(err, `zlib.Writer.Close failed`) return in.Bytes(), err } return in.Bytes(), nil @@ -35,15 +42,17 @@ func UnZlib(data []byte) ([]byte, error) { if data == nil || len(data) < 13 { return data, nil } - - b := bytes.NewReader(data) - var out bytes.Buffer - var err error - r, err := zlib.NewReader(b) + var ( + out bytes.Buffer + bytesReader = bytes.NewReader(data) + zlibReader, err = zlib.NewReader(bytesReader) + ) if err != nil { + err = gerror.Wrapf(err, `zlib.NewReader failed`) return nil, err } - if _, err = io.Copy(&out, r); err != nil { + if _, err = io.Copy(&out, zlibReader); err != nil { + err = gerror.Wrapf(err, `io.Copy failed`) return nil, err } return out.Bytes(), nil diff --git a/encoding/gini/gini.go b/encoding/gini/gini.go index 733d9385f..43dcdf25c 100644 --- a/encoding/gini/gini.go +++ b/encoding/gini/gini.go @@ -22,37 +22,38 @@ import ( // Decode converts INI format to map. func Decode(data []byte) (res map[string]interface{}, err error) { res = make(map[string]interface{}) - fieldMap := make(map[string]interface{}) + var ( + fieldMap = make(map[string]interface{}) + bytesReader = bytes.NewReader(data) + bufioReader = bufio.NewReader(bytesReader) + section string + lastSection string + haveSection bool + line string + ) - a := bytes.NewReader(data) - r := bufio.NewReader(a) - var section string - var lastSection string - var haveSection bool for { - line, err := r.ReadString('\n') + line, err = bufioReader.ReadString('\n') if err != nil { if err == io.EOF { break } + err = gerror.Wrapf(err, `bufioReader.ReadString failed`) return nil, err } - - lineStr := strings.TrimSpace(string(line)) - if len(lineStr) == 0 { + if line = strings.TrimSpace(line); len(line) == 0 { continue } - if lineStr[0] == ';' || lineStr[0] == '#' { + if line[0] == ';' || line[0] == '#' { continue } - - sectionBeginPos := strings.Index(lineStr, "[") - sectionEndPos := strings.Index(lineStr, "]") - + var ( + sectionBeginPos = strings.Index(line, "[") + sectionEndPos = strings.Index(line, "]") + ) if sectionBeginPos >= 0 && sectionEndPos >= 2 { - section = lineStr[sectionBeginPos+1 : sectionEndPos] - + section = line[sectionBeginPos+1 : sectionEndPos] if lastSection == "" { lastSection = section } else if lastSection != section { @@ -64,8 +65,8 @@ func Decode(data []byte) (res map[string]interface{}, err error) { continue } - if strings.Contains(lineStr, "=") && haveSection { - values := strings.Split(lineStr, "=") + if strings.Contains(line, "=") && haveSection { + values := strings.Split(line, "=") fieldMap[strings.TrimSpace(values[0])] = strings.TrimSpace(strings.Join(values[1:], "=")) res[section] = fieldMap } @@ -79,26 +80,26 @@ func Decode(data []byte) (res map[string]interface{}, err error) { // Encode converts map to INI format. func Encode(data map[string]interface{}) (res []byte, err error) { - w := new(bytes.Buffer) - w.WriteString("; this ini file is produced by package gini\n") + var ( + n int + w = new(bytes.Buffer) + ) for k, v := range data { - n, err := w.WriteString(fmt.Sprintf("[%s]\n", k)) + n, err = w.WriteString(fmt.Sprintf("[%s]\n", k)) if err != nil || n == 0 { - return nil, gerror.WrapCodef(gcode.CodeInternalError, err, "write data failed") + return nil, gerror.Wrapf(err, "w.WriteString failed") } for kk, vv := range v.(map[string]interface{}) { - n, err := w.WriteString(fmt.Sprintf("%s=%s\n", kk, vv.(string))) + n, err = w.WriteString(fmt.Sprintf("%s=%s\n", kk, vv.(string))) if err != nil || n == 0 { - return nil, gerror.WrapCodef(gcode.CodeInternalError, err, "write data failed") + return nil, gerror.Wrapf(err, "w.WriteString failed") } } } res = make([]byte, w.Len()) - n, err := w.Read(res) - if err != nil || n == 0 { - return nil, gerror.WrapCodef(gcode.CodeInternalError, err, "write data failed") + if n, err = w.Read(res); err != nil || n == 0 { + return nil, gerror.Wrapf(err, "w.Read failed") } - return res, nil } diff --git a/encoding/gjson/gjson.go b/encoding/gjson/gjson.go index 0f31e0212..a5cf93876 100644 --- a/encoding/gjson/gjson.go +++ b/encoding/gjson/gjson.go @@ -61,7 +61,7 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error { length = len(array) ) if value, err = j.convertValue(value); err != nil { - return gerror.Wrap(err, `Json Set failed`) + return err } // Initialization checks. if *j.p == nil { @@ -71,8 +71,10 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error { *j.p = make(map[string]interface{}) } } - var pparent *interface{} = nil // Parent pointer. - var pointer *interface{} = j.p // Current pointer. + var ( + pparent *interface{} = nil // Parent pointer. + pointer *interface{} = j.p // Current pointer. + ) j.mu.Lock() defer j.mu.Unlock() for i := 0; i < length; i++ { @@ -126,6 +128,7 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error { // Numeric index. valueNum, err := strconv.Atoi(array[i]) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `strconv.Atoi failed for string "%s"`, array[i]) return err } diff --git a/encoding/gjson/gjson_api_new_load.go b/encoding/gjson/gjson_api_new_load.go index 78eb38c25..7c6e4cc51 100644 --- a/encoding/gjson/gjson_api_new_load.go +++ b/encoding/gjson/gjson_api_new_load.go @@ -275,7 +275,7 @@ func doLoadContentWithOptions(dataType string, data []byte, options Options) (*J } switch result.(type) { case string, []byte: - return nil, gerror.NewCodef(gcode.CodeInternalError, `json decoding failed for content: %s`, data) + return nil, gerror.Newf(`json decoding failed for content: %s`, data) } return NewWithOptions(result, options), nil } diff --git a/encoding/gtoml/gtoml.go b/encoding/gtoml/gtoml.go index fe636f610..79137d6b8 100644 --- a/encoding/gtoml/gtoml.go +++ b/encoding/gtoml/gtoml.go @@ -11,6 +11,7 @@ import ( "bytes" "github.com/BurntSushi/toml" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/internal/json" ) @@ -18,6 +19,7 @@ import ( func Encode(v interface{}) ([]byte, error) { buffer := bytes.NewBuffer(nil) if err := toml.NewEncoder(buffer).Encode(v); err != nil { + err = gerror.Wrap(err, `toml.Encoder.Encode failed`) return nil, err } return buffer.Bytes(), nil @@ -26,13 +28,18 @@ func Encode(v interface{}) ([]byte, error) { func Decode(v []byte) (interface{}, error) { var result interface{} if err := toml.Unmarshal(v, &result); err != nil { + err = gerror.Wrap(err, `toml.Unmarshal failed`) return nil, err } return result, nil } -func DecodeTo(v []byte, result interface{}) error { - return toml.Unmarshal(v, result) +func DecodeTo(v []byte, result interface{}) (err error) { + err = toml.Unmarshal(v, result) + if err != nil { + err = gerror.Wrap(err, `toml.Unmarshal failed`) + } + return err } func ToJson(v []byte) ([]byte, error) { diff --git a/encoding/gurl/url.go b/encoding/gurl/url.go index 031c4e194..e64d0a28b 100644 --- a/encoding/gurl/url.go +++ b/encoding/gurl/url.go @@ -10,6 +10,8 @@ package gurl import ( "net/url" "strings" + + "github.com/gogf/gf/v2/errors/gerror" ) // Encode escapes the string so it can be safely placed @@ -53,6 +55,7 @@ func BuildQuery(queryData url.Values) string { func ParseURL(str string, component int) (map[string]string, error) { u, err := url.Parse(str) if err != nil { + err = gerror.Wrapf(err, `url.Parse failed for URL "%s"`, str) return nil, err } if component == -1 { diff --git a/encoding/gxml/gxml.go b/encoding/gxml/gxml.go index f1c61d441..efd3c7b1d 100644 --- a/encoding/gxml/gxml.go +++ b/encoding/gxml/gxml.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/clbanning/mxj/v2" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/encoding/gcharset" "github.com/gogf/gf/v2/text/gregex" @@ -22,7 +23,11 @@ func Decode(content []byte) (map[string]interface{}, error) { if err != nil { return nil, err } - return mxj.NewMapXml(res) + m, err := mxj.NewMapXml(res) + if err != nil { + err = gerror.Wrapf(err, `mxj.NewMapXml failed`) + } + return m, err } // DecodeWithoutRoot parses `content` into a map, and returns the map without root level. @@ -33,6 +38,7 @@ func DecodeWithoutRoot(content []byte) (map[string]interface{}, error) { } m, err := mxj.NewMapXml(res) if err != nil { + err = gerror.Wrapf(err, `mxj.NewMapXml failed`) return nil, err } for _, v := range m { @@ -46,13 +52,21 @@ func DecodeWithoutRoot(content []byte) (map[string]interface{}, error) { // Encode encodes map `m` to an XML format content as bytes. // The optional parameter `rootTag` is used to specify the XML root tag. func Encode(m map[string]interface{}, rootTag ...string) ([]byte, error) { - return mxj.Map(m).Xml(rootTag...) + b, err := mxj.Map(m).Xml(rootTag...) + if err != nil { + err = gerror.Wrapf(err, `mxj.Map.Xml failed`) + } + return b, err } // EncodeWithIndent encodes map `m` to an XML format content as bytes with indent. // The optional parameter `rootTag` is used to specify the XML root tag. func EncodeWithIndent(m map[string]interface{}, rootTag ...string) ([]byte, error) { - return mxj.Map(m).XmlIndent("", "\t", rootTag...) + b, err := mxj.Map(m).XmlIndent("", "\t", rootTag...) + if err != nil { + err = gerror.Wrapf(err, `mxj.Map.XmlIndent failed`) + } + return b, err } // ToJson converts `content` as XML format into JSON format bytes. @@ -63,6 +77,7 @@ func ToJson(content []byte) ([]byte, error) { } mv, err := mxj.NewMapXml(res) if err == nil { + err = gerror.Wrapf(err, `mxj.NewMapXml failed`) return mv.Json() } return nil, err @@ -70,12 +85,11 @@ func ToJson(content []byte) ([]byte, error) { // convert does convert the encoding of given XML content from XML root tag into UTF-8 encoding content. func convert(xml []byte) (res []byte, err error) { - patten := `<\?xml.*encoding\s*=\s*['|"](.*?)['|"].*\?>` - matchStr, err := gregex.MatchString(patten, string(xml)) - if err != nil { - return nil, err - } - xmlEncode := "UTF-8" + var ( + patten = `<\?xml.*encoding\s*=\s*['|"](.*?)['|"].*\?>` + matchStr, _ = gregex.MatchString(patten, string(xml)) + xmlEncode = "UTF-8" + ) if len(matchStr) == 2 { xmlEncode = matchStr[1] } diff --git a/encoding/gyaml/gyaml.go b/encoding/gyaml/gyaml.go index 143834dc0..1fbdda593 100644 --- a/encoding/gyaml/gyaml.go +++ b/encoding/gyaml/gyaml.go @@ -17,7 +17,7 @@ import ( func Encode(value interface{}) (out []byte, err error) { if out, err = yaml.Marshal(value); err != nil { - err = gerror.Wrap(err, `encode value to yaml failed`) + err = gerror.Wrap(err, `yaml.Marshal failed`) } return } @@ -28,7 +28,7 @@ func Decode(value []byte) (interface{}, error) { err error ) if err = yaml.Unmarshal(value, &result); err != nil { - err = gerror.Wrap(err, `decode yaml failed`) + err = gerror.Wrap(err, `yaml.Unmarshal failed`) return nil, err } return gconv.MapDeep(result), nil @@ -37,7 +37,7 @@ func Decode(value []byte) (interface{}, error) { func DecodeTo(value []byte, result interface{}) (err error) { err = yaml.Unmarshal(value, result) if err != nil { - err = gerror.Wrap(err, `encode yaml to value failed`) + err = gerror.Wrap(err, `yaml.Unmarshal failed`) } return } @@ -49,9 +49,6 @@ func ToJson(value []byte) (out []byte, err error) { if result, err = Decode(value); err != nil { return nil, err } else { - if out, err = json.Marshal(result); err != nil { - err = gerror.Wrap(err, `convert yaml to json failed`) - } - return out, err + return json.Marshal(result) } } diff --git a/errors/gerror/gerror.go b/errors/gerror/gerror.go index 09ddedc18..ac11e323d 100644 --- a/errors/gerror/gerror.go +++ b/errors/gerror/gerror.go @@ -12,6 +12,7 @@ package gerror import ( "fmt" + "strings" "github.com/gogf/gf/v2/errors/gcode" ) @@ -145,13 +146,9 @@ func WrapSkipf(skip int, err error, format string, args ...interface{}) error { // NewCode creates and returns an error that has error code and given text. func NewCode(code gcode.Code, text ...string) error { - errText := "" - if len(text) > 0 { - errText = text[0] - } return &Error{ stack: callers(), - text: errText, + text: strings.Join(text, ", "), code: code, } } @@ -168,13 +165,9 @@ func NewCodef(code gcode.Code, format string, args ...interface{}) error { // NewCodeSkip creates and returns an error which has error code and is formatted from given text. // The parameter `skip` specifies the stack callers skipped amount. func NewCodeSkip(code gcode.Code, skip int, text ...string) error { - errText := "" - if len(text) > 0 { - errText = text[0] - } return &Error{ stack: callers(skip), - text: errText, + text: strings.Join(text, ", "), code: code, } } @@ -195,14 +188,10 @@ func WrapCode(code gcode.Code, err error, text ...string) error { if err == nil { return nil } - errText := "" - if len(text) > 0 { - errText = text[0] - } return &Error{ error: err, stack: callers(), - text: errText, + text: strings.Join(text, ", "), code: code, } } @@ -228,14 +217,10 @@ func WrapCodeSkip(code gcode.Code, skip int, err error, text ...string) error { if err == nil { return nil } - errText := "" - if len(text) > 0 { - errText = text[0] - } return &Error{ error: err, stack: callers(skip), - text: errText, + text: strings.Join(text, ", "), code: code, } } diff --git a/frame/gins/gins_redis.go b/frame/gins/gins_redis.go index 6d67b59ac..7c2ccca39 100644 --- a/frame/gins/gins_redis.go +++ b/frame/gins/gins_redis.go @@ -11,7 +11,6 @@ import ( "fmt" "github.com/gogf/gf/v2/database/gredis" - "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/gutil" @@ -44,7 +43,7 @@ func Redis(name ...string) *gredis.Redis { ) if configData, err := Config().Data(ctx); err != nil { - panic(gerror.WrapCode(gcode.CodeOperationFailed, err, `retrieving redis configuration failed`)) + panic(gerror.Wrap(err, `retrieving redis configuration failed`)) } else { if _, v := gutil.MapPossibleItemByKey(configData, configNodeNameRedis); v != nil { configMap = gconv.Map(v) diff --git a/internal/json/json.go b/internal/json/json.go index ae6c38f13..89832110f 100644 --- a/internal/json/json.go +++ b/internal/json/json.go @@ -11,34 +11,52 @@ import ( "bytes" "encoding/json" "io" + + "github.com/gogf/gf/v2/errors/gerror" ) // Marshal adapts to json/encoding Marshal API. // // Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API // Refer to https://godoc.org/encoding/json#Marshal for more information. -func Marshal(v interface{}) ([]byte, error) { - return json.Marshal(v) +func Marshal(v interface{}) (marshaledBytes []byte, err error) { + marshaledBytes, err = json.Marshal(v) + if err != nil { + err = gerror.Wrap(err, `json.Marshal failed`) + } + return } // MarshalIndent same as json.MarshalIndent. Prefix is not supported. -func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { - return json.MarshalIndent(v, prefix, indent) +func MarshalIndent(v interface{}, prefix, indent string) (marshaledBytes []byte, err error) { + marshaledBytes, err = json.MarshalIndent(v, prefix, indent) + if err != nil { + err = gerror.Wrap(err, `json.MarshalIndent failed`) + } + return } // Unmarshal adapts to json/encoding Unmarshal API // // Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. // Refer to https://godoc.org/encoding/json#Unmarshal for more information. -func Unmarshal(data []byte, v interface{}) error { - return json.Unmarshal(data, v) +func Unmarshal(data []byte, v interface{}) (err error) { + err = json.Unmarshal(data, v) + if err != nil { + err = gerror.Wrap(err, `json.Unmarshal failed`) + } + return } // UnmarshalUseNumber decodes the json data bytes to target interface using number option. -func UnmarshalUseNumber(data []byte, v interface{}) error { +func UnmarshalUseNumber(data []byte, v interface{}) (err error) { decoder := NewDecoder(bytes.NewReader(data)) decoder.UseNumber() - return decoder.Decode(v) + err = decoder.Decode(v) + if err != nil { + err = gerror.Wrap(err, `json.UnmarshalUseNumber failed`) + } + return } // NewEncoder same as json.NewEncoder @@ -50,7 +68,7 @@ func NewEncoder(writer io.Writer) *json.Encoder { // // NewDecoder returns a new decoder that reads from r. // -// Instead of a json/encoding Decoder, an Decoder is returned +// Instead of a json/encoding Decoder, a Decoder is returned // Refer to https://godoc.org/encoding/json#NewDecoder for more information. func NewDecoder(reader io.Reader) *json.Decoder { return json.NewDecoder(reader) diff --git a/internal/utils/utils_io.go b/internal/utils/utils_io.go index 9da382d4e..f51bbe3b8 100644 --- a/internal/utils/utils_io.go +++ b/internal/utils/utils_io.go @@ -9,6 +9,8 @@ package utils import ( "io" "io/ioutil" + + "github.com/gogf/gf/v2/errors/gerror" ) // ReadCloser implements the io.ReadCloser interface @@ -34,6 +36,7 @@ func NewReadCloser(content []byte, repeatable bool) io.ReadCloser { func NewReadCloserWithReadCloser(r io.ReadCloser, repeatable bool) (io.ReadCloser, error) { content, err := ioutil.ReadAll(r) if err != nil { + err = gerror.Wrapf(err, `ioutil.ReadAll failed`) return nil, err } defer r.Close() diff --git a/net/gclient/gclient.go b/net/gclient/gclient.go index 6b1bd6ad4..fcb110da8 100644 --- a/net/gclient/gclient.go +++ b/net/gclient/gclient.go @@ -20,10 +20,10 @@ import ( "strings" "time" + "github.com/gogf/gf/v2/internal/intlog" "golang.org/x/net/proxy" "github.com/gogf/gf/v2" - "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/os/gfile" "github.com/gogf/gf/v2/text/gregex" @@ -193,6 +193,7 @@ func (c *Client) SetProxy(proxyURL string) { } _proxy, err := url.Parse(proxyURL) if err != nil { + intlog.Error(context.TODO(), err) return } if _proxy.Scheme == "http" { @@ -202,7 +203,6 @@ func (c *Client) SetProxy(proxyURL string) { } else { var auth = &proxy.Auth{} user := _proxy.User.Username() - if user != "" { auth.User = user password, hasPassword := _proxy.User.Password() @@ -223,6 +223,7 @@ func (c *Client) SetProxy(proxyURL string) { }, ) if err != nil { + intlog.Error(context.TODO(), err) return } if v, ok := c.Transport.(*http.Transport); ok { @@ -238,14 +239,14 @@ func (c *Client) SetProxy(proxyURL string) { func (c *Client) SetTLSKeyCrt(crtFile, keyFile string) error { tlsConfig, err := LoadKeyCrt(crtFile, keyFile) if err != nil { - return gerror.WrapCode(gcode.CodeInternalError, err, "LoadKeyCrt failed") + return gerror.Wrap(err, "LoadKeyCrt failed") } if v, ok := c.Transport.(*http.Transport); ok { tlsConfig.InsecureSkipVerify = true v.TLSClientConfig = tlsConfig return nil } - return gerror.NewCode(gcode.CodeInternalError, `cannot set TLSClientConfig for custom Transport of the client`) + return gerror.New(`cannot set TLSClientConfig for custom Transport of the client`) } // SetTLSConfig sets the TLS configuration of client. @@ -254,7 +255,7 @@ func (c *Client) SetTLSConfig(tlsConfig *tls.Config) error { v.TLSClientConfig = tlsConfig return nil } - return gerror.NewCode(gcode.CodeInternalError, `cannot set TLSClientConfig for custom Transport of the client`) + return gerror.New(`cannot set TLSClientConfig for custom Transport of the client`) } // LoadKeyCrt creates and returns a TLS configuration object with given certificate and key files. @@ -269,6 +270,7 @@ func LoadKeyCrt(crtFile, keyFile string) (*tls.Config, error) { } crt, err := tls.LoadX509KeyPair(crtPath, keyPath) if err != nil { + err = gerror.Wrapf(err, `tls.LoadX509KeyPair failed for certFile "%s", keyFile "%s"`, crtPath, keyPath) return nil, err } tlsConfig := &tls.Config{} diff --git a/net/gclient/gclient_bytes.go b/net/gclient/gclient_bytes.go index aa3f1fee6..17a5c0fc7 100644 --- a/net/gclient/gclient_bytes.go +++ b/net/gclient/gclient_bytes.go @@ -62,10 +62,11 @@ func (c *Client) TraceBytes(ctx context.Context, url string, data ...interface{} func (c *Client) RequestBytes(ctx context.Context, method string, url string, data ...interface{}) []byte { response, err := c.DoRequest(ctx, method, url, data...) if err != nil { + intlog.Error(ctx, err) return nil } defer func() { - if err := response.Close(); err != nil { + if err = response.Close(); err != nil { intlog.Error(ctx, err) } }() diff --git a/net/gclient/gclient_dump.go b/net/gclient/gclient_dump.go index 3c63e9aa7..9372a55bc 100644 --- a/net/gclient/gclient_dump.go +++ b/net/gclient/gclient_dump.go @@ -12,6 +12,7 @@ import ( "net/http" "net/http/httputil" + "github.com/gogf/gf/v2/internal/intlog" "github.com/gogf/gf/v2/internal/utils" ) @@ -45,6 +46,7 @@ func (r *Response) RawRequest() string { // DumpRequestOut writes more request headers than DumpRequest, such as User-Agent. bs, err := httputil.DumpRequestOut(r.request, false) if err != nil { + intlog.Error(r.request.Context(), err) return "" } return fmt.Sprintf( @@ -63,6 +65,7 @@ func (r *Response) RawResponse() string { } bs, err := httputil.DumpResponse(r.Response, false) if err != nil { + intlog.Error(r.request.Context(), err) return "" } diff --git a/net/gclient/gclient_request.go b/net/gclient/gclient_request.go index 0c3701c29..777fecb97 100644 --- a/net/gclient/gclient_request.go +++ b/net/gclient/gclient_request.go @@ -21,7 +21,6 @@ import ( "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/internal/httputil" - "github.com/gogf/gf/v2/internal/intlog" "github.com/gogf/gf/v2/internal/json" "github.com/gogf/gf/v2/internal/utils" "github.com/gogf/gf/v2/os/gfile" @@ -175,6 +174,7 @@ func (c *Client) prepareRequest(ctx context.Context, method, url string, data .. bodyBuffer = bytes.NewBuffer(nil) } if req, err = http.NewRequest(method, url, bodyBuffer); err != nil { + err = gerror.Wrapf(err, `http.NewRequest failed with method "%s" and URL "%s"`, method, url) return nil, err } } else { @@ -191,25 +191,35 @@ func (c *Client) prepareRequest(ctx context.Context, method, url string, data .. if !gfile.Exists(path) { return nil, gerror.NewCodef(gcode.CodeInvalidParameter, `"%s" does not exist`, path) } - if file, err := writer.CreateFormFile(array[0], gfile.Basename(path)); err == nil { - if f, err := os.Open(path); err == nil { + var ( + file io.Writer + formFileName = gfile.Basename(path) + formFieldName = array[0] + ) + if file, err = writer.CreateFormFile(formFieldName, formFileName); err != nil { + err = gerror.Wrapf(err, `writer.CreateFormFile failed with "%s", "%s"`, formFieldName, formFileName) + return nil, err + } else { + var f *os.File + if f, err = os.Open(path); err == nil { + err = gerror.Wrapf(err, `os.Open failed for name "%s"`, path) + return nil, err + } else { if _, err = io.Copy(file, f); err != nil { - if err := f.Close(); err != nil { - intlog.Errorf(ctx, `%+v`, err) - } + err = gerror.Wrapf(err, `io.Copy failed from "%s" to form "%s"`, path, formFieldName) + _ = f.Close() return nil, err } - if err := f.Close(); err != nil { - intlog.Errorf(ctx, `%+v`, err) - } - } else { - return nil, err + _ = f.Close() } - } else { - return nil, err } } else { - if err = writer.WriteField(array[0], array[1]); err != nil { + var ( + fieldName = array[0] + fieldValue = array[1] + ) + if err = writer.WriteField(fieldName, fieldValue); err != nil { + err = gerror.Wrapf(err, `writer.WriteField failed with "%s", "%s"`, fieldName, fieldValue) return nil, err } } @@ -217,10 +227,12 @@ func (c *Client) prepareRequest(ctx context.Context, method, url string, data .. // Close finishes the multipart message and writes the trailing // boundary end line to the output. if err = writer.Close(); err != nil { + err = gerror.Wrapf(err, `writer.Close failed`) return nil, err } if req, err = http.NewRequest(method, url, buffer); err != nil { + err = gerror.Wrapf(err, `http.NewRequest failed for method "%s" and URL "%s"`, method, url) return nil, err } else { req.Header.Set("Content-Type", writer.FormDataContentType()) @@ -229,6 +241,7 @@ func (c *Client) prepareRequest(ctx context.Context, method, url string, data .. // Normal request. paramBytes := []byte(params) if req, err = http.NewRequest(method, url, bytes.NewReader(paramBytes)); err != nil { + err = gerror.Wrapf(err, `http.NewRequest failed for method "%s" and URL "%s"`, method, url) return nil, err } else { if v, ok := c.header["Content-Type"]; ok { @@ -236,7 +249,7 @@ func (c *Client) prepareRequest(ctx context.Context, method, url string, data .. req.Header.Set("Content-Type", v) } else if len(paramBytes) > 0 { if (paramBytes[0] == '[' || paramBytes[0] == '{') && json.Valid(paramBytes) { - // Auto detecting and setting the post content format: JSON. + // Auto-detecting and setting the post content format: JSON. req.Header.Set("Content-Type", "application/json") } else if gregex.IsMatchString(`^[\w\[\]]+=.+`, params) { // If the parameters passed like "name=value", it then uses form type. @@ -259,8 +272,8 @@ func (c *Client) prepareRequest(ctx context.Context, method, url string, data .. } // It's necessary set the req.Host if you want to custom the host value of the request. // It uses the "Host" value from header if it's not empty. - if host := req.Header.Get("Host"); host != "" { - req.Host = host + if reqHeaderHost := req.Header.Get("Host"); host != "" { + req.Host = reqHeaderHost } // Custom Cookie. if len(c.cookies) > 0 { @@ -285,7 +298,6 @@ func (c *Client) prepareRequest(ctx context.Context, method, url string, data .. // callRequest sends request with give http.Request, and returns the responses object. // Note that the response object MUST be closed if it'll never be used. func (c *Client) callRequest(req *http.Request) (resp *Response, err error) { - ctx := req.Context() resp = &Response{ request: req, } @@ -297,11 +309,10 @@ func (c *Client) callRequest(req *http.Request) (resp *Response, err error) { req.Body = utils.NewReadCloser(reqBodyContent, false) for { if resp.Response, err = c.Do(req); err != nil { + err = gerror.Wrapf(err, `request failed`) // The response might not be nil when err != nil. if resp.Response != nil { - if err := resp.Response.Body.Close(); err != nil { - intlog.Errorf(ctx, `%+v`, err) - } + _ = resp.Response.Body.Close() } if c.retryCount > 0 { c.retryCount-- diff --git a/net/gclient/gclient_response.go b/net/gclient/gclient_response.go index 6f3226889..9dec919cb 100644 --- a/net/gclient/gclient_response.go +++ b/net/gclient/gclient_response.go @@ -9,6 +9,8 @@ package gclient import ( "io/ioutil" "net/http" + + "github.com/gogf/gf/v2/internal/intlog" ) // Response is the struct for client request response. @@ -56,6 +58,7 @@ func (r *Response) ReadAll() []byte { } body, err := ioutil.ReadAll(r.Response.Body) if err != nil { + intlog.Error(r.request.Context(), err) return nil } return body diff --git a/net/ghttp/ghttp_request_param.go b/net/ghttp/ghttp_request_param.go index c6c146972..c6afe25e0 100644 --- a/net/ghttp/ghttp_request_param.go +++ b/net/ghttp/ghttp_request_param.go @@ -247,12 +247,12 @@ func (r *Request) parseForm() { if gstr.Contains(contentType, "multipart/") { // multipart/form-data, multipart/mixed if err = r.ParseMultipartForm(r.Server.config.FormParsingMemory); err != nil { - panic(gerror.WrapCode(gcode.CodeInvalidRequest, err, "")) + panic(gerror.WrapCode(gcode.CodeInvalidRequest, err, "r.ParseMultipartForm failed")) } } else if gstr.Contains(contentType, "form") { // application/x-www-form-urlencoded if err = r.Request.ParseForm(); err != nil { - panic(gerror.WrapCode(gcode.CodeInvalidRequest, err, "")) + panic(gerror.WrapCode(gcode.CodeInvalidRequest, err, "r.Request.ParseForm failed")) } } if len(r.PostForm) > 0 { @@ -295,7 +295,7 @@ func (r *Request) parseForm() { } if params != "" { if r.formMap, err = gstr.Parse(params); err != nil { - panic(gerror.WrapCode(gcode.CodeInvalidParameter, err, "")) + panic(gerror.WrapCode(gcode.CodeInvalidParameter, err, "Parse request parameters failed")) } } } diff --git a/net/ghttp/ghttp_request_param_file.go b/net/ghttp/ghttp_request_param_file.go index 9918c5c68..0b624cb76 100644 --- a/net/ghttp/ghttp_request_param_file.go +++ b/net/ghttp/ghttp_request_param_file.go @@ -52,6 +52,7 @@ func (f *UploadFile) Save(dirPath string, randomlyRename ...bool) (filename stri file, err := f.Open() if err != nil { + err = gerror.Wrapf(err, `UploadFile.Open failed`) return "", err } defer file.Close() @@ -68,7 +69,8 @@ func (f *UploadFile) Save(dirPath string, randomlyRename ...bool) (filename stri } defer newFile.Close() intlog.Printf(f.ctx, `save upload file: %s`, filePath) - if _, err := io.Copy(newFile, file); err != nil { + if _, err = io.Copy(newFile, file); err != nil { + err = gerror.Wrapf(err, `io.Copy failed from "%s" to "%s"`, f.Filename, filePath) return "", err } return gfile.Basename(filePath), nil diff --git a/net/ghttp/ghttp_response_cors.go b/net/ghttp/ghttp_response_cors.go index f7dbfe107..d18fbc9b5 100644 --- a/net/ghttp/ghttp_response_cors.go +++ b/net/ghttp/ghttp_response_cors.go @@ -11,6 +11,8 @@ import ( "net/http" "net/url" + "github.com/gogf/gf/v2/errors/gcode" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/text/gstr" "github.com/gogf/gf/v2/util/gconv" ) @@ -117,6 +119,7 @@ func (r *Response) CORSAllowedOrigin(options CORSOptions) bool { } parsed, err := url.Parse(origin) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `url.Parse failed for URL "%s"`, origin) return false } for _, v := range options.AllowDomain { diff --git a/net/ghttp/ghttp_server.go b/net/ghttp/ghttp_server.go index a19d60559..9de2d9978 100644 --- a/net/ghttp/ghttp_server.go +++ b/net/ghttp/ghttp_server.go @@ -186,7 +186,7 @@ func (s *Server) Start() error { path = gfile.Join(s.config.SessionPath, s.name) if !gfile.Exists(path) { if err := gfile.Mkdir(path); err != nil { - return gerror.WrapCodef(gcode.CodeInternalError, err, `mkdir failed for "%s"`, path) + return gerror.Wrapf(err, `mkdir failed for "%s"`, path) } } } diff --git a/net/ghttp/ghttp_server_graceful.go b/net/ghttp/ghttp_server_graceful.go index 898043933..d60aa9868 100644 --- a/net/ghttp/ghttp_server_graceful.go +++ b/net/ghttp/ghttp_server_graceful.go @@ -14,7 +14,6 @@ import ( "net/http" "os" - "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/os/gproc" "github.com/gogf/gf/v2/os/gres" @@ -126,7 +125,7 @@ func (s *gracefulServer) ListenAndServeTLS(certFile, keyFile string, tlsConfig . } if err != nil { - return gerror.WrapCodef(gcode.CodeInternalError, err, `open cert file "%s","%s" failed`, certFile, keyFile) + return gerror.Wrapf(err, `open certFile "%s" and keyFile "%s" failed`, certFile, keyFile) } ln, err := s.getNetListener() if err != nil { @@ -174,13 +173,13 @@ func (s *gracefulServer) getNetListener() (net.Listener, error) { f := os.NewFile(s.fd, "") ln, err = net.FileListener(f) if err != nil { - err = gerror.WrapCodef(gcode.CodeInternalError, err, "%d: net.FileListener failed", gproc.Pid()) + err = gerror.Wrapf(err, "%d: net.FileListener failed", gproc.Pid()) return nil, err } } else { ln, err = net.Listen("tcp", s.httpServer.Addr) if err != nil { - err = gerror.WrapCodef(gcode.CodeInternalError, err, "%d: net.Listen failed", gproc.Pid()) + err = gerror.Wrapf(err, "%d: net.Listen failed", gproc.Pid()) } } return ln, err diff --git a/net/ghttp/ghttp_server_router_group.go b/net/ghttp/ghttp_server_router_group.go index 91eba0dc7..75535c02b 100644 --- a/net/ghttp/ghttp_server_router_group.go +++ b/net/ghttp/ghttp_server_router_group.go @@ -299,7 +299,7 @@ func (g *RouterGroup) doBindRoutersToServer(ctx context.Context, item *preBindIt if len(prefix) > 0 { domain, method, path, err := g.server.parsePattern(pattern) if err != nil { - g.server.Logger().Fatalf(ctx, "invalid pattern: %s", pattern) + g.server.Logger().Fatalf(ctx, "invalid route pattern: %s", pattern) } // If there is already a domain, unset the domain field in the pattern. if g.domain != nil { diff --git a/net/ghttp/ghttp_server_router_serve.go b/net/ghttp/ghttp_server_router_serve.go index 0b0f61bd9..8ae683d97 100644 --- a/net/ghttp/ghttp_server_router_serve.go +++ b/net/ghttp/ghttp_server_router_serve.go @@ -12,7 +12,6 @@ import ( "strings" "github.com/gogf/gf/v2/container/glist" - "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/internal/intlog" "github.com/gogf/gf/v2/internal/json" @@ -202,7 +201,7 @@ func (s *Server) searchHandlers(method, path, domain string) (parsedItems []*han parsedItemList.PushBack(parsedItem) default: - panic(gerror.NewCodef(gcode.CodeInternalError, `invalid handler type %s`, item.Type)) + panic(gerror.Newf(`invalid handler type %s`, item.Type)) } } } diff --git a/net/gipv4/gipv4_ip.go b/net/gipv4/gipv4_ip.go index fe977a9e7..8e270cf6a 100644 --- a/net/gipv4/gipv4_ip.go +++ b/net/gipv4/gipv4_ip.go @@ -20,6 +20,7 @@ import ( func GetIpArray() (ips []string, err error) { interfaceAddr, err := net.InterfaceAddrs() if err != nil { + err = gerror.Wrap(err, `net.InterfaceAddrs failed`) return nil, err } for _, address := range interfaceAddr { @@ -47,9 +48,14 @@ func GetIntranetIp() (ip string, err error) { // GetIntranetIpArray retrieves and returns the intranet ip list of current machine. func GetIntranetIpArray() (ips []string, err error) { - interFaces, e := net.Interfaces() - if e != nil { - return ips, e + var ( + addresses []net.Addr + interFaces []net.Interface + ) + interFaces, err = net.Interfaces() + if err != nil { + err = gerror.Wrap(err, `net.Interfaces failed`) + return ips, err } for _, interFace := range interFaces { if interFace.Flags&net.FlagUp == 0 { @@ -64,9 +70,10 @@ func GetIntranetIpArray() (ips []string, err error) { if strings.HasPrefix(interFace.Name, "w-") { continue } - addresses, e := interFace.Addrs() - if e != nil { - return ips, e + addresses, err = interFace.Addrs() + if err != nil { + err = gerror.Wrap(err, `interFace.Addrs failed`) + return ips, err } for _, addr := range addresses { var ip net.IP @@ -120,6 +127,7 @@ func IsIntranet(ip string) bool { if array[0] == "172" { second, err := strconv.ParseInt(array[1], 10, 64) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `strconv.ParseInt failed for string "%s"`, array[1]) return false } if second >= 16 && second <= 31 { diff --git a/net/gipv4/gipv4_mac.go b/net/gipv4/gipv4_mac.go index 78c6e21cd..a09520554 100644 --- a/net/gipv4/gipv4_mac.go +++ b/net/gipv4/gipv4_mac.go @@ -9,6 +9,8 @@ package gipv4 import ( "net" + + "github.com/gogf/gf/v2/errors/gerror" ) // GetMac retrieves and returns the first mac address of current host. @@ -27,6 +29,7 @@ func GetMac() (mac string, err error) { func GetMacArray() (macs []string, err error) { netInterfaces, err := net.Interfaces() if err != nil { + err = gerror.Wrap(err, `net.Interfaces failed`) return nil, err } for _, netInterface := range netInterfaces { diff --git a/os/gcfg/gcfg_adapter_file.go b/os/gcfg/gcfg_adapter_file.go index 1260f8b6e..f3a7115d7 100644 --- a/os/gcfg/gcfg_adapter_file.go +++ b/os/gcfg/gcfg_adapter_file.go @@ -13,7 +13,6 @@ import ( "github.com/gogf/gf/v2/container/gmap" "github.com/gogf/gf/v2/container/gvar" "github.com/gogf/gf/v2/encoding/gjson" - "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/internal/command" "github.com/gogf/gf/v2/internal/intlog" @@ -270,9 +269,9 @@ func (c *AdapterFile) getJson(fileName ...string) (configJson *gjson.Json, err e } if err != nil { if filePath != "" { - err = gerror.WrapCodef(gcode.CodeOperationFailed, err, `load config file "%s" failed`, filePath) + err = gerror.Wrapf(err, `load config file "%s" failed`, filePath) } else { - err = gerror.WrapCode(gcode.CodeOperationFailed, err, `load configuration failed`) + err = gerror.Wrap(err, `load configuration failed`) } } return nil diff --git a/os/gfile/gfile_home.go b/os/gfile/gfile_home.go index 68bc6c645..817d6aaa9 100644 --- a/os/gfile/gfile_home.go +++ b/os/gfile/gfile_home.go @@ -58,7 +58,7 @@ func homeUnix() (string, error) { result := strings.TrimSpace(stdout.String()) if result == "" { - return "", gerror.NewCode(gcode.CodeInternalError, "blank output when reading home directory") + return "", gerror.New("blank output when reading home directory") } return result, nil diff --git a/os/gfpool/gfpool_file.go b/os/gfpool/gfpool_file.go index 290615171..2a774ad2f 100644 --- a/os/gfpool/gfpool_file.go +++ b/os/gfpool/gfpool_file.go @@ -11,7 +11,6 @@ import ( "os" "time" - "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" ) @@ -43,7 +42,7 @@ func Open(path string, flag int, perm os.FileMode, ttl ...time.Duration) (file * // Stat returns the FileInfo structure describing file. func (f *File) Stat() (os.FileInfo, error) { if f.stat == nil { - return nil, gerror.NewCode(gcode.CodeInternalError, "file stat is empty") + return nil, gerror.New("file stat is empty") } return f.stat, nil } diff --git a/os/glog/glog_logger_config.go b/os/glog/glog_logger_config.go index 5dfa6a99b..d3aa8d970 100644 --- a/os/glog/glog_logger_config.go +++ b/os/glog/glog_logger_config.go @@ -212,7 +212,7 @@ func (l *Logger) SetPath(path string) error { } if !gfile.Exists(path) { if err := gfile.Mkdir(path); err != nil { - return gerror.WrapCodef(gcode.CodeOperationFailed, err, `Mkdir "%s" failed in PWD "%s"`, path, gfile.Pwd()) + return gerror.Wrapf(err, `Mkdir "%s" failed in PWD "%s"`, path, gfile.Pwd()) } } l.config.Path = strings.TrimRight(path, gfile.Separator) diff --git a/os/grpool/grpool.go b/os/grpool/grpool.go index 6aa97af04..ba9c6e46d 100644 --- a/os/grpool/grpool.go +++ b/os/grpool/grpool.go @@ -116,7 +116,7 @@ func (p *Pool) AddWithRecover(ctx context.Context, userFunc Func, recoverFunc .. if v, ok := exception.(error); ok && gerror.HasStack(v) { recoverFunc[0](v) } else { - recoverFunc[0](gerror.NewCodef(gcode.CodeInternalError, `%+v`, exception)) + recoverFunc[0](gerror.Newf(`%+v`, exception)) } } } diff --git a/os/gsession/gsession_storage_file.go b/os/gsession/gsession_storage_file.go index c8a4d2877..b7b7abdf8 100644 --- a/os/gsession/gsession_storage_file.go +++ b/os/gsession/gsession_storage_file.go @@ -53,7 +53,7 @@ func NewStorageFile(path ...string) *StorageFile { } if storagePath != "" { if err := gfile.Mkdir(storagePath); err != nil { - panic(gerror.WrapCodef(gcode.CodeInternalError, err, `Mkdir "%s" failed in PWD "%s"`, path, gfile.Pwd())) + panic(gerror.Wrapf(err, `Mkdir "%s" failed in PWD "%s"`, path, gfile.Pwd())) } } s := &StorageFile{ diff --git a/os/gstructs/gstructs_tag.go b/os/gstructs/gstructs_tag.go index 8621ad9e0..d513fa9af 100644 --- a/os/gstructs/gstructs_tag.go +++ b/os/gstructs/gstructs_tag.go @@ -7,10 +7,11 @@ package gstructs import ( - "errors" "reflect" "strconv" + "github.com/gogf/gf/v2/errors/gcode" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/util/gtag" ) @@ -154,7 +155,10 @@ exitLoop: reflectKind = reflectValue.Kind() } if reflectKind != reflect.Struct { - return nil, errors.New("given value should be either type of struct/*struct/[]struct/[]*struct") + return nil, gerror.NewCode( + gcode.CodeInvalidParameter, + "given value should be either type of struct/*struct/[]struct/[]*struct", + ) } var ( structType = reflectValue.Type() diff --git a/os/gstructs/gstructs_type.go b/os/gstructs/gstructs_type.go index 1d0caf39b..82d24de61 100644 --- a/os/gstructs/gstructs_type.go +++ b/os/gstructs/gstructs_type.go @@ -7,9 +7,9 @@ package gstructs import ( - "errors" - "fmt" "reflect" + + "github.com/gogf/gf/v2/errors/gerror" ) // StructType retrieves and returns the struct Type of specified struct/*struct. @@ -49,11 +49,9 @@ func StructType(object interface{}) (*Type, error) { exitLoop: if reflectKind != reflect.Struct { - return nil, errors.New( - fmt.Sprintf( - `invalid object kind "%s", kind of "struct" is required`, - reflectKind, - ), + return nil, gerror.Newf( + `invalid object kind "%s", kind of "struct" is required`, + reflectKind, ) } reflectType = reflectValue.Type() diff --git a/os/gtime/gtime.go b/os/gtime/gtime.go index d4d5a9877..7447db57b 100644 --- a/os/gtime/gtime.go +++ b/os/gtime/gtime.go @@ -10,6 +10,7 @@ package gtime import ( + "context" "fmt" "os" "regexp" @@ -19,6 +20,7 @@ import ( "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/internal/intlog" "github.com/gogf/gf/v2/internal/utils" "github.com/gogf/gf/v2/text/gregex" ) @@ -257,7 +259,7 @@ func StrToTime(str string, format ...string) (*Time, error) { } return NewFromTime(time.Date(0, time.Month(1), 1, hour, min, sec, nsec, local)), nil } else { - return nil, gerror.NewCode(gcode.CodeInvalidParameter, "unsupported time format") + return nil, gerror.NewCodef(gcode.CodeInvalidParameter, `unsupported time converting for string "%s"`, str) } // Time @@ -270,7 +272,7 @@ func StrToTime(str string, format ...string) (*Time, error) { min, _ = strconv.Atoi(s[2:4]) sec, _ = strconv.Atoi(s[4:6]) } - // Nanoseconds, check and perform bit filling + // Nanoseconds, check and perform bits filling if len(match[3]) > 0 { nsec, _ = strconv.Atoi(match[3]) for i := 0; i < 9-len(match[3]); i++ { @@ -292,7 +294,7 @@ func StrToTime(str string, format ...string) (*Time, error) { m, _ := strconv.Atoi(zone[2:4]) s, _ := strconv.Atoi(zone[4:6]) if h > 24 || m > 59 || s > 59 { - return nil, gerror.NewCodef(gcode.CodeInvalidParameter, "invalid zone string: %s", match[6]) + return nil, gerror.NewCodef(gcode.CodeInvalidParameter, `invalid zone string "%s"`, match[6]) } // Comparing the given time zone whether equals to current time zone, // it converts it to UTC if they does not equal. @@ -331,7 +333,7 @@ func StrToTime(str string, format ...string) (*Time, error) { } } if month <= 0 || day <= 0 { - return nil, gerror.NewCodef(gcode.CodeInvalidParameter, "invalid time string:%s", str) + return nil, gerror.NewCodef(gcode.CodeInvalidParameter, `invalid time string "%s"`, str) } return NewFromTime(time.Date(year, time.Month(month), day, hour, min, sec, nsec, local)), nil } @@ -343,14 +345,25 @@ func ConvertZone(strTime string, toZone string, fromZone ...string) (*Time, erro if err != nil { return nil, err } + var l *time.Location if len(fromZone) > 0 { - if l, err := time.LoadLocation(fromZone[0]); err != nil { + if l, err = time.LoadLocation(fromZone[0]); err != nil { + err = gerror.WrapCodef( + gcode.CodeInvalidParameter, err, + `time.LoadLocation failed for name "%s"`, + fromZone[0], + ) return nil, err } else { t.Time = time.Date(t.Year(), time.Month(t.Month()), t.Day(), t.Hour(), t.Minute(), t.Time.Second(), t.Time.Nanosecond(), l) } } - if l, err := time.LoadLocation(toZone); err != nil { + if l, err = time.LoadLocation(toZone); err != nil { + err = gerror.WrapCodef( + gcode.CodeInvalidParameter, err, + `time.LoadLocation failed for name "%s"`, + toZone, + ) return nil, err } else { return t.ToLocation(l), nil @@ -369,25 +382,37 @@ func StrToTimeLayout(str string, layout string) (*Time, error) { if t, err := time.ParseInLocation(layout, str, time.Local); err == nil { return NewFromTime(t), nil } else { - return nil, err + return nil, gerror.WrapCodef( + gcode.CodeInvalidParameter, err, + `time.ParseInLocation failed for layout "%s" and value "%s"`, + layout, str, + ) } } // ParseTimeFromContent retrieves time information for content string, it then parses and returns it // as *Time object. -// It returns the first time information if there're more than one time string in the content. +// It returns the first time information if there are more than one time string in the content. // It only retrieves and parses the time information with given `format` if it's passed. func ParseTimeFromContent(content string, format ...string) *Time { + var ( + err error + match []string + ) if len(format) > 0 { - if match, err := gregex.MatchString(formatToRegexPattern(format[0]), content); err == nil && len(match) > 0 { + match, err = gregex.MatchString(formatToRegexPattern(format[0]), content) + if err != nil { + intlog.Error(context.TODO(), err) + } + if len(match) > 0 { return NewFromStrFormat(match[0], format[0]) } } else { - if match := timeRegex1.FindStringSubmatch(content); len(match) >= 1 { + if match = timeRegex1.FindStringSubmatch(content); len(match) >= 1 { return NewFromStr(strings.Trim(match[0], "./_- \n\r")) - } else if match := timeRegex2.FindStringSubmatch(content); len(match) >= 1 { + } else if match = timeRegex2.FindStringSubmatch(content); len(match) >= 1 { return NewFromStr(strings.Trim(match[0], "./_- \n\r")) - } else if match := timeRegex3.FindStringSubmatch(content); len(match) >= 1 { + } else if match = timeRegex3.FindStringSubmatch(content); len(match) >= 1 { return NewFromStr(strings.Trim(match[0], "./_- \n\r")) } } @@ -401,26 +426,38 @@ func ParseTimeFromContent(content string, format ...string) *Time { // Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h", "d". // // Very note that it supports unit "d" more than function time.ParseDuration. -func ParseDuration(s string) (time.Duration, error) { +func ParseDuration(s string) (duration time.Duration, err error) { + var ( + num int64 + ) if utils.IsNumeric(s) { - v, err := strconv.ParseInt(s, 10, 64) + num, err = strconv.ParseInt(s, 10, 64) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `strconv.ParseInt failed for string "%s"`, s) return 0, err } - return time.Duration(v), nil + return time.Duration(num), nil } match, err := gregex.MatchString(`^([\-\d]+)[dD](.*)$`, s) if err != nil { return 0, err } if len(match) == 3 { - v, err := strconv.ParseInt(match[1], 10, 64) + num, err = strconv.ParseInt(match[1], 10, 64) if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `strconv.ParseInt failed for string "%s"`, match[1]) return 0, err } - return time.ParseDuration(fmt.Sprintf(`%dh%s`, v*24, match[2])) + s = fmt.Sprintf(`%dh%s`, num*24, match[2]) + duration, err = time.ParseDuration(s) + if err != nil { + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `time.ParseDuration failed for string "%s"`, s) + } + return } - return time.ParseDuration(s) + duration, err = time.ParseDuration(s) + err = gerror.WrapCodef(gcode.CodeInvalidParameter, err, `time.ParseDuration failed for string "%s"`, s) + return } // FuncCost calculates the cost time of function `f` in nanoseconds. diff --git a/os/gview/gview_parse.go b/os/gview/gview_parse.go index 7922d6b6e..5638069ba 100644 --- a/os/gview/gview_parse.go +++ b/os/gview/gview_parse.go @@ -116,7 +116,7 @@ func (view *View) Parse(ctx context.Context, file string, params ...Params) (res tpl, err = tpl.(*texttpl.Template).Parse(item.content) } if err != nil && item.path != "" { - err = gerror.WrapCode(gcode.CodeInternalError, err, item.path) + err = gerror.Wrap(err, item.path) } }) if err != nil { diff --git a/protocol/goai/goai_parameter.go b/protocol/goai/goai_parameter.go index 5350e5830..082bd60e4 100644 --- a/protocol/goai/goai_parameter.go +++ b/protocol/goai/goai_parameter.go @@ -56,7 +56,7 @@ func (oai *OpenApiV3) newParameterRefWithStructMethod(field gstructs.Field, path if len(tagMap) > 0 { err := gconv.Struct(oai.fileMapWithShortTags(tagMap), parameter) if err != nil { - return nil, gerror.WrapCode(gcode.CodeInternalError, err, `mapping struct tags to Parameter failed`) + return nil, gerror.Wrap(err, `mapping struct tags to Parameter failed`) } } if parameter.In == "" { diff --git a/protocol/goai/goai_path.go b/protocol/goai/goai_path.go index 566c51042..4f9125f82 100644 --- a/protocol/goai/goai_path.go +++ b/protocol/goai/goai_path.go @@ -127,10 +127,10 @@ func (oai *OpenApiV3) addPath(in addPathInput) error { if len(inputMetaMap) > 0 { if err := gconv.Struct(oai.fileMapWithShortTags(inputMetaMap), &path); err != nil { - return gerror.WrapCode(gcode.CodeInternalError, err, `mapping struct tags to Path failed`) + return gerror.Wrap(err, `mapping struct tags to Path failed`) } if err := gconv.Struct(oai.fileMapWithShortTags(inputMetaMap), &operation); err != nil { - return gerror.WrapCode(gcode.CodeInternalError, err, `mapping struct tags to Operation failed`) + return gerror.Wrap(err, `mapping struct tags to Operation failed`) } } @@ -205,7 +205,7 @@ func (oai *OpenApiV3) addPath(in addPathInput) error { ) if len(outputMetaMap) > 0 { if err := gconv.Struct(oai.fileMapWithShortTags(outputMetaMap), &response); err != nil { - return gerror.WrapCode(gcode.CodeInternalError, err, `mapping struct tags to Response failed`) + return gerror.Wrap(err, `mapping struct tags to Response failed`) } } // Supported mime types of response. diff --git a/protocol/goai/goai_shema.go b/protocol/goai/goai_shema.go index 1e0ef9e78..ada8c6e9c 100644 --- a/protocol/goai/goai_shema.go +++ b/protocol/goai/goai_shema.go @@ -9,7 +9,6 @@ package goai import ( "reflect" - "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/os/gstructs" "github.com/gogf/gf/v2/text/gstr" @@ -118,7 +117,7 @@ func (oai *OpenApiV3) structToSchema(object interface{}) (*Schema, error) { if len(tagMap) > 0 { err := gconv.Struct(oai.fileMapWithShortTags(tagMap), schema) if err != nil { - return nil, gerror.WrapCode(gcode.CodeInternalError, err, `mapping meta data tags to Schema failed`) + return nil, gerror.Wrap(err, `mapping meta data tags to Schema failed`) } } if schema.Type != "" && schema.Type != TypeObject { diff --git a/protocol/goai/goai_shemaref.go b/protocol/goai/goai_shemaref.go index 9dcd97ff1..14d356686 100644 --- a/protocol/goai/goai_shemaref.go +++ b/protocol/goai/goai_shemaref.go @@ -9,7 +9,6 @@ package goai import ( "reflect" - "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/internal/json" "github.com/gogf/gf/v2/util/gconv" @@ -34,7 +33,7 @@ func (oai *OpenApiV3) newSchemaRefWithGolangType(golangType reflect.Type, tagMap ) if len(tagMap) > 0 { if err := gconv.Struct(oai.fileMapWithShortTags(tagMap), schema); err != nil { - return nil, gerror.WrapCode(gcode.CodeInternalError, err, `mapping struct tags to Schema failed`) + return nil, gerror.Wrap(err, `mapping struct tags to Schema failed`) } } schemaRef.Value = schema diff --git a/util/gconv/gconv_struct.go b/util/gconv/gconv_struct.go index b945aa882..03b3a5839 100644 --- a/util/gconv/gconv_struct.go +++ b/util/gconv/gconv_struct.go @@ -322,7 +322,7 @@ func bindVarToStructAttr(elem reflect.Value, name string, value interface{}, map defer func() { if exception := recover(); exception != nil { if err = bindVarToReflectValue(structFieldValue, value, mapping); err != nil { - err = gerror.WrapCodef(gcode.CodeInternalError, err, `error binding value to attribute "%s"`, name) + err = gerror.Wrapf(err, `error binding value to attribute "%s"`, name) } } }() diff --git a/util/gutil/gutil.go b/util/gutil/gutil.go index 172798b1c..1771e1e89 100644 --- a/util/gutil/gutil.go +++ b/util/gutil/gutil.go @@ -11,7 +11,6 @@ import ( "fmt" "reflect" - "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/internal/empty" "github.com/gogf/gf/v2/util/gconv" @@ -34,7 +33,7 @@ func Try(try func()) (err error) { if v, ok := exception.(error); ok && gerror.HasStack(v) { err = v } else { - err = gerror.NewCodef(gcode.CodeInternalError, `%+v`, exception) + err = gerror.Newf(`%+v`, exception) } } }()