Skip to content

Commit 6e19cb9

Browse files
committed
move join function into pkg and add tests
This commit moves the newly added `Join` implementation that mirrors the go 1.20 stdlib function. Some simple unit tests are added and `Join` wrappers are also integrated into the datadriven formatting test. Our existing format code for multi-cause errors is compatible with this new type which allows us to remove the custom formatter from the implementation.
1 parent deb8e12 commit 6e19cb9

16 files changed

+2514
-64
lines changed

errutil_api.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/cockroachdb/errors/barriers"
1919
"github.com/cockroachdb/errors/errbase"
2020
"github.com/cockroachdb/errors/errutil"
21+
"github.com/cockroachdb/errors/join"
2122
)
2223

2324
// New creates an error with a simple error message.
@@ -192,3 +193,13 @@ func HandleAsAssertionFailureDepth(depth int, origErr error) error {
192193
// - it also supports recursing through causes with Cause().
193194
// - if it detects an API use error, its panic object is a valid error.
194195
func As(err error, target interface{}) bool { return errutil.As(err, target) }
196+
197+
// Join returns an error that wraps the given errors.
198+
// Any nil error values are discarded.
199+
// Join returns nil if errs contains no non-nil values.
200+
// The error formats as the concatenation of the strings obtained
201+
// by calling the Error method of each element of errs, with a newline
202+
// between each string.
203+
func Join(errs ...error) error {
204+
return join.Join(errs...)
205+
}

fmttests/datadriven_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"github.com/cockroachdb/errors/errutil"
3838
"github.com/cockroachdb/errors/hintdetail"
3939
"github.com/cockroachdb/errors/issuelink"
40+
"github.com/cockroachdb/errors/join"
4041
"github.com/cockroachdb/errors/report"
4142
"github.com/cockroachdb/errors/safedetails"
4243
"github.com/cockroachdb/errors/secondary"
@@ -262,6 +263,9 @@ var wrapCommands = map[string]commandFn{
262263
ctx = logtags.AddTag(ctx, "safe", redact.Safe(456))
263264
return contexttags.WithContextTags(err, ctx)
264265
},
266+
"join": func(err error, args []arg) error {
267+
return join.Join(err, errutil.New(strfy(args)))
268+
},
265269
}
266270

267271
var noPrefixWrappers = map[string]bool{
@@ -286,6 +290,7 @@ var noPrefixWrappers = map[string]bool{
286290
"stack": true,
287291
"tags": true,
288292
"telemetry": true,
293+
"join": true,
289294
}
290295

291296
var wrapOnlyExceptions = map[string]string{}
@@ -315,6 +320,7 @@ func init() {
315320
// means they don't match.
316321
"nofmt",
317322
"errorf",
323+
"join",
318324
} {
319325
wrapOnlyExceptions[v] = `
320326
accept %\+v via Formattable.*IRREGULAR: not same as %\+v

fmttests/testdata/format/wrap-fmt

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,6 +2251,198 @@ Type: "*fmttests.errFmt"
22512251
Title: "×"
22522252
(NO STACKTRACE)
22532253

2254+
run
2255+
fmt innerone innertwo
2256+
join outerthree outerfour
2257+
2258+
accept %\+v via Formattable.*IRREGULAR: not same as %\+v
2259+
accept %\#v via Formattable.*IRREGULAR: not same as %\#v
2260+
2261+
require (?s)
2262+
----
2263+
&join.joinError{
2264+
errs: {
2265+
&fmttests.errFmt{msg:"innerone\ninnertwo"},
2266+
&withstack.withStack{
2267+
cause: &errutil.leafError{msg:"outerthree\nouterfour"},
2268+
stack: &stack{...},
2269+
},
2270+
},
2271+
}
2272+
=====
2273+
===== non-redactable formats
2274+
=====
2275+
== %#v
2276+
&join.joinError{errs:[]error{(*fmttests.errFmt)(0xAAAABBBB), (*withstack.withStack)(0xAAAABBBB)}}
2277+
== Error()
2278+
innerone
2279+
innertwo
2280+
outerthree
2281+
outerfour
2282+
== %v = Error(), good
2283+
== %s = Error(), good
2284+
== %q = quoted Error(), good
2285+
== %x = hex Error(), good
2286+
== %X = HEX Error(), good
2287+
== %+v = Error(), ok
2288+
== %#v via Formattable() (IRREGULAR: not same as %#v)
2289+
&join.joinError{
2290+
errs: {
2291+
&fmttests.errFmt{msg:"innerone\ninnertwo"},
2292+
&withstack.withStack{
2293+
cause: &errutil.leafError{msg:"outerthree\nouterfour"},
2294+
stack: &stack{...},
2295+
},
2296+
},
2297+
}
2298+
== %v via Formattable() = Error(), good
2299+
== %s via Formattable() = %v via Formattable(), good
2300+
== %q via Formattable() = quoted %v via Formattable(), good
2301+
== %+v via Formattable() (IRREGULAR: not same as %+v)
2302+
innerone
2303+
(1) innerone
2304+
| innertwo
2305+
| outerthree
2306+
| outerfour
2307+
Wraps: (2) attached stack trace
2308+
-- stack trace:
2309+
| github.com/cockroachdb/errors/fmttests.glob...funcNN...
2310+
| <tab><path>:<lineno>
2311+
| github.com/cockroachdb/errors/fmttests.TestDatadriven.func2.1
2312+
| <tab><path>:<lineno>
2313+
| github.com/cockroachdb/datadriven.runDirective.func1
2314+
| <tab><path>:<lineno>
2315+
| github.com/cockroachdb/datadriven.runDirective
2316+
| <tab><path>:<lineno>
2317+
| github.com/cockroachdb/datadriven.runDirectiveOrSubTest
2318+
| <tab><path>:<lineno>
2319+
| github.com/cockroachdb/datadriven.runTestInternal
2320+
| <tab><path>:<lineno>
2321+
| github.com/cockroachdb/datadriven.RunTest
2322+
| <tab><path>:<lineno>
2323+
| github.com/cockroachdb/errors/fmttests.TestDatadriven.func2
2324+
| <tab><path>:<lineno>
2325+
| github.com/cockroachdb/datadriven.Walk
2326+
| <tab><path>:<lineno>
2327+
| github.com/cockroachdb/datadriven.Walk.func1
2328+
| <tab><path>:<lineno>
2329+
| testing.tRunner
2330+
| <tab><path>:<lineno>
2331+
| runtime.goexit
2332+
| <tab><path>:<lineno>
2333+
└─ Wraps: (3) outerthree
2334+
| outerfour
2335+
Wraps: (4) innerone
2336+
| innertwo
2337+
| -- this is innerone
2338+
| innertwo's
2339+
| multi-line leaf payload
2340+
Error types: (1) *join.joinError (2) *withstack.withStack (3) *errutil.leafError (4) *fmttests.errFmt
2341+
=====
2342+
===== redactable formats
2343+
=====
2344+
== printed via redact Print(), ok - congruent with %v
2345+
‹innerone›
2346+
‹innertwo›
2347+
‹outerthree›
2348+
‹outerfour›
2349+
== printed via redact Printf() %v = Print(), good
2350+
== printed via redact Printf() %s = Print(), good
2351+
== printed via redact Printf() %q, refused - good
2352+
== printed via redact Printf() %x, refused - good
2353+
== printed via redact Printf() %X, refused - good
2354+
== printed via redact Printf() %+v, ok - congruent with %+v via Formattable()
2355+
‹innerone›
2356+
(1) ‹innerone›
2357+
‹ | innertwo›
2358+
‹ | outerthree›
2359+
‹ | outerfour›
2360+
Wraps: (2) attached stack trace
2361+
-- stack trace:
2362+
| github.com/cockroachdb/errors/fmttests.glob...funcNN...
2363+
| <tab><path>:<lineno>
2364+
| github.com/cockroachdb/errors/fmttests.TestDatadriven.func2.1
2365+
| <tab><path>:<lineno>
2366+
| github.com/cockroachdb/datadriven.runDirective.func1
2367+
| <tab><path>:<lineno>
2368+
| github.com/cockroachdb/datadriven.runDirective
2369+
| <tab><path>:<lineno>
2370+
| github.com/cockroachdb/datadriven.runDirectiveOrSubTest
2371+
| <tab><path>:<lineno>
2372+
| github.com/cockroachdb/datadriven.runTestInternal
2373+
| <tab><path>:<lineno>
2374+
| github.com/cockroachdb/datadriven.RunTest
2375+
| <tab><path>:<lineno>
2376+
| github.com/cockroachdb/errors/fmttests.TestDatadriven.func2
2377+
| <tab><path>:<lineno>
2378+
| github.com/cockroachdb/datadriven.Walk
2379+
| <tab><path>:<lineno>
2380+
| github.com/cockroachdb/datadriven.Walk.func1
2381+
| <tab><path>:<lineno>
2382+
| testing.tRunner
2383+
| <tab><path>:<lineno>
2384+
| runtime.goexit
2385+
| <tab><path>:<lineno>
2386+
└─ Wraps: (3) outerthree
2387+
| outerfour
2388+
Wraps: (4) ‹innerone›
2389+
‹ | innertwo›
2390+
‹ | -- this is innerone›
2391+
‹ | innertwo's›
2392+
‹ | multi-line leaf payload›
2393+
Error types: (1) *join.joinError (2) *withstack.withStack (3) *errutil.leafError (4) *fmttests.errFmt
2394+
=====
2395+
===== Sentry reporting
2396+
=====
2397+
== Message payload
2398+
×
2399+
(1) ×
2400+
×
2401+
×
2402+
×
2403+
Wraps: (2) attached stack trace
2404+
-- stack trace:
2405+
| github.com/cockroachdb/errors/fmttests.glob...funcNN...
2406+
| <tab><path>:<lineno>
2407+
| github.com/cockroachdb/errors/fmttests.TestDatadriven.func2.1
2408+
| <tab><path>:<lineno>
2409+
| github.com/cockroachdb/datadriven.runDirective.func1
2410+
| <tab><path>:<lineno>
2411+
| github.com/cockroachdb/datadriven.runDirective
2412+
| <tab><path>:<lineno>
2413+
| github.com/cockroachdb/datadriven.runDirectiveOrSubTest
2414+
| <tab><path>:<lineno>
2415+
| github.com/cockroachdb/datadriven.runTestInternal
2416+
| <tab><path>:<lineno>
2417+
| github.com/cockroachdb/datadriven.RunTest
2418+
| <tab><path>:<lineno>
2419+
| github.com/cockroachdb/errors/fmttests.TestDatadriven.func2
2420+
| <tab><path>:<lineno>
2421+
| github.com/cockroachdb/datadriven.Walk
2422+
| <tab><path>:<lineno>
2423+
| github.com/cockroachdb/datadriven.Walk.func1
2424+
| <tab><path>:<lineno>
2425+
| testing.tRunner
2426+
| <tab><path>:<lineno>
2427+
| runtime.goexit
2428+
| <tab><path>:<lineno>
2429+
└─ Wraps: (3) outerthree
2430+
| outerfour
2431+
Wraps: (4) ×
2432+
×
2433+
×
2434+
×
2435+
×
2436+
Error types: (1) *join.joinError (2) *withstack.withStack (3) *errutil.leafError (4) *fmttests.errFmt
2437+
-- report composition:
2438+
*join.joinError
2439+
== Extra "error types"
2440+
github.com/cockroachdb/errors/join/*join.joinError (*::)
2441+
== Exception 1 (Module: "error domain: <none>")
2442+
Type: "*join.joinError"
2443+
Title: "×"
2444+
(NO STACKTRACE)
2445+
22542446
run
22552447
fmt innerone innertwo
22562448
migrated outerthree outerfour

0 commit comments

Comments
 (0)