Skip to content

Commit e6d54eb

Browse files
authored
Merge pull request #1 from muonsoft/joining
Joining
2 parents 21bcd07 + 7634999 commit e6d54eb

12 files changed

Lines changed: 469 additions & 56 deletions

File tree

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
- name: Set up Go
1414
uses: actions/setup-go@v2
1515
with:
16-
go-version: ^1.13
16+
go-version: ^1.20
1717
id: go
1818

1919
- name: Checkout code
@@ -25,7 +25,7 @@ jobs:
2525
- name: Run golangci-lint
2626
uses: golangci/golangci-lint-action@v2
2727
with:
28-
version: v1.46
28+
version: v1.52
2929

3030
- name: Run tests
3131
run: go test -v $(go list ./... | grep -v vendor)

.golangci.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,13 @@ linters:
77
- bidichk
88
- bodyclose
99
- contextcheck
10-
- cyclop
11-
- deadcode
1210
- depguard
1311
- dogsled
1412
- dupl
1513
- durationcheck
1614
- exportloopref
1715
- forbidigo
1816
- funlen
19-
- gci
2017
- gocognit
2118
- goconst
2219
- gocritic
@@ -46,7 +43,6 @@ linters:
4643
- predeclared
4744
- promlinter
4845
- revive
49-
- structcheck
5046
- stylecheck
5147
- tenv
5248
- testpackage
@@ -56,7 +52,6 @@ linters:
5652
- unconvert
5753
- unparam
5854
- unused
59-
- varcheck
6055
- whitespace
6156

6257
issues:
@@ -84,3 +79,9 @@ issues:
8479
- errcheck
8580
- goconst
8681
- gocritic
82+
83+
linters-settings:
84+
revive:
85+
rules:
86+
- name: var-naming
87+
disabled: true

errors.go

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,25 @@ func As[T any](err error) (T, bool) {
6969
return t, true
7070
}
7171
}
72-
err = Unwrap(err)
72+
switch x := err.(type) {
73+
case interface{ Unwrap() error }:
74+
err = x.Unwrap()
75+
if err == nil {
76+
var z T
77+
return z, false
78+
}
79+
case interface{ Unwrap() []error }:
80+
for _, err := range x.Unwrap() {
81+
if t, ok := As[T](err); ok {
82+
return t, ok
83+
}
84+
}
85+
var z T
86+
return z, false
87+
default:
88+
var z T
89+
return z, false
90+
}
7391
}
7492

7593
var z T
@@ -106,8 +124,8 @@ func Errorf(message string, argsAndOptions ...interface{}) error {
106124
opts := newOptions(options...)
107125
err := fmt.Errorf(message, args...)
108126

109-
argError := getArgError(message, args)
110-
if isWrapper(argError) {
127+
argErrors := getArgErrors(message, args)
128+
if len(argErrors) == 1 && isWrapper(argErrors[0]) {
111129
return &wrapped{wrapped: err, fields: opts.fields}
112130
}
113131

@@ -126,12 +144,16 @@ func Wrap(err error, options ...Option) error {
126144
if err == nil {
127145
return nil
128146
}
129-
opts := newOptions(options...)
130-
131147
if isWrapper(err) {
132-
return &wrapped{wrapped: err, fields: opts.fields}
148+
if len(options) == 0 {
149+
return err
150+
}
151+
152+
return &wrapped{wrapped: err, fields: newOptions(options...).fields}
133153
}
134154

155+
opts := newOptions(options...)
156+
135157
return &stacked{
136158
wrapped: &wrapped{wrapped: err, fields: opts.fields},
137159
stack: newStack(opts.skipCallers),
@@ -230,7 +252,13 @@ func (e *stacked) Format(s fmt.State, verb rune) {
230252
func (e *stacked) MarshalJSON() ([]byte, error) {
231253
data := mapWriter{"error": e.Error()}
232254
data.SetStackTrace(e.StackTrace())
233-
e.LogFields(data)
255+
256+
var err error
257+
for err = e; err != nil; err = Unwrap(err) {
258+
if loggable, ok := err.(LoggableError); ok {
259+
loggable.LogFields(data)
260+
}
261+
}
234262

235263
return json.Marshal(data)
236264
}
@@ -254,28 +282,30 @@ func splitArgsAndOptions(argsAndOptions []interface{}) ([]interface{}, []Option)
254282
return args, options
255283
}
256284

257-
func getArgError(message string, args []interface{}) error {
258-
index := getErrorIndex(message)
285+
func getArgErrors(message string, args []interface{}) []error {
286+
indices := getErrorIndices(message)
287+
errs := make([]error, 0, len(indices))
259288

260-
if index >= 0 && index < len(args) {
261-
if err, ok := args[index].(error); ok {
262-
return err
289+
for _, i := range indices {
290+
if err, ok := args[i].(error); ok {
291+
errs = append(errs, err)
263292
}
264293
}
265294

266-
return nil
295+
return errs
267296
}
268297

269-
func getErrorIndex(message string) int {
270-
i := -1
298+
func getErrorIndices(message string) []int {
299+
indices := make([]int, 0, 1)
271300
isFormat := false
272301

302+
i := -1
273303
for _, s := range message {
274304
if isFormat {
275305
if s != '%' {
276306
i++
277307
if s == 'w' {
278-
return i
308+
indices = append(indices, i)
279309
}
280310
}
281311
isFormat = false
@@ -284,7 +314,7 @@ func getErrorIndex(message string) int {
284314
}
285315
}
286316

287-
return -1
317+
return indices
288318
}
289319

290320
type mapWriter map[string]interface{}

0 commit comments

Comments
 (0)