mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
This pull request refactors the error handling code to improve support for error text formatting with arguments, making it easier to retrieve both the error message template and its arguments (useful for i18n and structured error handling). It introduces the new `ITextArgs` interface, updates error constructors to store format strings and arguments separately, and adds methods to retrieve them. Several usages and tests are updated to reflect these changes. ### Error formatting and argument support * Introduced the `ITextArgs` interface to allow errors to expose their text template and arguments separately, supporting advanced use cases like internationalization (`errors/gerror/gerror.go`). * Updated the `Error` struct to include an `args` field for error arguments, and added methods `TextWithArgs()`, `Text()`, and `Args()` to retrieve formatted error text, the template, and arguments respectively (`errors/gerror/gerror_error.go`). [[1]](diffhunk://#diff-b56b52e546735b8196ec3e8bd25c0b007ac134e2f13b116ee3abcb2f92c3bdd9R23) [[2]](diffhunk://#diff-b56b52e546735b8196ec3e8bd25c0b007ac134e2f13b116ee3abcb2f92c3bdd9L121-R145) * Changed all error creation and wrapping functions (e.g., `Newf`, `Wrapf`, `NewCodef`, etc.) to store the format string and arguments separately, rather than pre-formatting the error text (`errors/gerror/gerror_api.go`, `errors/gerror/gerror_api_code.go`). [[1]](diffhunk://#diff-847475c1de42114004c50163aa2f34a4095e05122b4c2993aa3df4e5923e83cbL24-R27) [[2]](diffhunk://#diff-847475c1de42114004c50163aa2f34a4095e05122b4c2993aa3df4e5923e83cbL43-R48) [[3]](diffhunk://#diff-847475c1de42114004c50163aa2f34a4095e05122b4c2993aa3df4e5923e83cbL77-R78) [[4]](diffhunk://#diff-31ee6b1493f4b206c060a98818226b1b78102c91b5ae22e34ed4d1bb4a38c185L25-R29) [[5]](diffhunk://#diff-31ee6b1493f4b206c060a98818226b1b78102c91b5ae22e34ed4d1bb4a38c185L44-R50) [[6]](diffhunk://#diff-31ee6b1493f4b206c060a98818226b1b78102c91b5ae22e34ed4d1bb4a38c185L77-R79) [[7]](diffhunk://#diff-31ee6b1493f4b206c060a98818226b1b78102c91b5ae22e34ed4d1bb4a38c185L107-R110) * Updated the `Option` struct and related constructor to handle error arguments (`errors/gerror/gerror_api_option.go`). [[1]](diffhunk://#diff-4b458af6df9a0d8289303cf408b082ed472360b286cdc5a556c8fe7541973caaR16) [[2]](diffhunk://#diff-4b458af6df9a0d8289303cf408b082ed472360b286cdc5a556c8fe7541973caaR26) ### Code and test improvements * Updated formatting and equality checks to use the new methods for retrieving formatted error text and arguments, ensuring consistent behavior (`errors/gerror/gerror_error.go`, `errors/gerror/gerror_error_format.go`). [[1]](diffhunk://#diff-b56b52e546735b8196ec3e8bd25c0b007ac134e2f13b116ee3abcb2f92c3bdd9L45-R46) [[2]](diffhunk://#diff-fa801ef307f6c6fdda49fe9853593de29eda5b4d3712ea5bf9ed39de6e6859ebL26-R26) * Improved unit tests to verify the new interface and argument handling, including tests for the `ITextArgs` interface (`errors/gerror/gerror_z_unit_test.go`). * Minor code cleanup, such as removing unused imports and updating comments for clarity (`errors/gerror/gerror_api.go`, `errors/gerror/gerror_api_code.go`, `errors/gerror/gerror_error_json.go`). [[1]](diffhunk://#diff-847475c1de42114004c50163aa2f34a4095e05122b4c2993aa3df4e5923e83cbL10-L11) [[2]](diffhunk://#diff-31ee6b1493f4b206c060a98818226b1b78102c91b5ae22e34ed4d1bb4a38c185L10) [[3]](diffhunk://#diff-3e4ba207e242eb338f31f1091466374e8e72754a8969d92724bfb5c6b88f25edL15-R15) These changes make error handling more flexible and maintainable, especially for scenarios where error messages need to be localized or programmatically inspected. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
143 lines
3.5 KiB
Go
143 lines
3.5 KiB
Go
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
|
//
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
// If a copy of the MIT was not distributed with this file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
package gerror
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/gogf/gf/v2/errors/gcode"
|
|
)
|
|
|
|
// NewCode creates and returns an error that has error code and given text.
|
|
func NewCode(code gcode.Code, text ...string) error {
|
|
return &Error{
|
|
stack: callers(),
|
|
text: strings.Join(text, commaSeparatorSpace),
|
|
code: code,
|
|
}
|
|
}
|
|
|
|
// NewCodef returns an error that has error code and formats as the given format and args.
|
|
func NewCodef(code gcode.Code, format string, args ...any) error {
|
|
return &Error{
|
|
stack: callers(),
|
|
text: format,
|
|
args: args,
|
|
code: code,
|
|
}
|
|
}
|
|
|
|
// 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 {
|
|
return &Error{
|
|
stack: callers(skip),
|
|
text: strings.Join(text, commaSeparatorSpace),
|
|
code: code,
|
|
}
|
|
}
|
|
|
|
// NewCodeSkipf returns an error that has error code and formats as the given format and args.
|
|
// The parameter `skip` specifies the stack callers skipped amount.
|
|
func NewCodeSkipf(code gcode.Code, skip int, format string, args ...any) error {
|
|
return &Error{
|
|
stack: callers(skip),
|
|
text: format,
|
|
args: args,
|
|
code: code,
|
|
}
|
|
}
|
|
|
|
// WrapCode wraps error with code and text.
|
|
// It returns nil if given err is nil.
|
|
func WrapCode(code gcode.Code, err error, text ...string) error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
return &Error{
|
|
error: err,
|
|
stack: callers(),
|
|
text: strings.Join(text, commaSeparatorSpace),
|
|
code: code,
|
|
}
|
|
}
|
|
|
|
// WrapCodef wraps error with code and format specifier.
|
|
// It returns nil if given `err` is nil.
|
|
func WrapCodef(code gcode.Code, err error, format string, args ...any) error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
return &Error{
|
|
error: err,
|
|
stack: callers(),
|
|
text: format,
|
|
args: args,
|
|
code: code,
|
|
}
|
|
}
|
|
|
|
// WrapCodeSkip wraps error with code and text.
|
|
// It returns nil if given err is nil.
|
|
// The parameter `skip` specifies the stack callers skipped amount.
|
|
func WrapCodeSkip(code gcode.Code, skip int, err error, text ...string) error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
return &Error{
|
|
error: err,
|
|
stack: callers(skip),
|
|
text: strings.Join(text, commaSeparatorSpace),
|
|
code: code,
|
|
}
|
|
}
|
|
|
|
// WrapCodeSkipf wraps error with code and text that is formatted with given format and args.
|
|
// It returns nil if given err is nil.
|
|
// The parameter `skip` specifies the stack callers skipped amount.
|
|
func WrapCodeSkipf(code gcode.Code, skip int, err error, format string, args ...any) error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
return &Error{
|
|
error: err,
|
|
stack: callers(skip),
|
|
text: format,
|
|
args: args,
|
|
code: code,
|
|
}
|
|
}
|
|
|
|
// Code returns the error code of `current error`.
|
|
// It returns `CodeNil` if it has no error code neither it does not implement interface Code.
|
|
func Code(err error) gcode.Code {
|
|
if err == nil {
|
|
return gcode.CodeNil
|
|
}
|
|
if e, ok := err.(ICode); ok {
|
|
return e.Code()
|
|
}
|
|
if e, ok := err.(IUnwrap); ok {
|
|
return Code(e.Unwrap())
|
|
}
|
|
return gcode.CodeNil
|
|
}
|
|
|
|
// HasCode checks and reports whether `err` has `code` in its chaining errors.
|
|
func HasCode(err error, code gcode.Code) bool {
|
|
if err == nil {
|
|
return false
|
|
}
|
|
if e, ok := err.(ICode); ok && code == e.Code() {
|
|
return true
|
|
}
|
|
if e, ok := err.(IUnwrap); ok {
|
|
return HasCode(e.Unwrap(), code)
|
|
}
|
|
return false
|
|
}
|