@@ -55,38 +55,66 @@ func (c *CommandConfig) ListAllLocations(
5555 return c .Printer (columns ).Prefix ("items" ).Print (data )
5656 }
5757
58- // Multi-location: query all concurrently
58+ // Build all configs before spawning goroutines to avoid racing
59+ // on client.Must() singleton (getters.go URL-change rebuild is not synchronized).
60+ type locConfig struct {
61+ location string
62+ cfg * shared.Configuration
63+ }
64+ configs := make ([]locConfig , len (locations ))
65+ for i , loc := range locations {
66+ normalizedLoc := strings .ReplaceAll (loc , "/" , "-" )
67+ url := fmt .Sprintf (templateURL , normalizedLoc )
68+ configs [i ] = locConfig {location : loc , cfg : client .NewRegionalConfig (url )}
69+ }
70+
71+ // Query all locations concurrently
5972 results := make ([]locResult , len (locations ))
6073 var wg sync.WaitGroup
6174
62- for i , loc := range locations {
75+ for i , lc := range configs {
6376 wg .Add (1 )
64- go func (i int , loc string ) {
77+ go func (i int , lc locConfig ) {
6578 defer wg .Done ()
66-
67- normalizedLoc := strings .ReplaceAll (loc , "/" , "-" )
68- url := fmt .Sprintf (templateURL , normalizedLoc )
69- cfg := client .NewRegionalConfig (url )
70-
71- data , err := fetchFn (cfg )
72- results [i ] = locResult {location : loc , data : data , err : err }
73- }(i , loc )
79+ data , err := fetchFn (lc .cfg )
80+ results [i ] = locResult {location : lc .location , data : data , err : err }
81+ }(i , lc )
7482 }
7583 wg .Wait ()
7684
77- // Check if all failed
85+ // Collect errors, deduplicate identical messages
7886 var lastErr error
7987 anySuccess := false
88+ errCounts := map [string ][]string {} // error message → list of locations
8089 for _ , r := range results {
8190 if r .err != nil {
8291 lastErr = r .err
83- fmt .Fprintf (c .Command .Command .ErrOrStderr (), "WARN: failed to list from %s: %v\n " , r .location , r .err )
92+ msg := r .err .Error ()
93+ errCounts [msg ] = append (errCounts [msg ], r .location )
8494 } else {
8595 anySuccess = true
8696 }
8797 }
98+
8899 if ! anySuccess {
89- return fmt .Errorf ("failed to list from any location: %w" , lastErr )
100+ // All failed — return single error, no warnings
101+ if len (errCounts ) == 1 {
102+ return fmt .Errorf ("failed to list from all locations: %w" , lastErr )
103+ }
104+ // Multiple distinct errors — join them
105+ var parts []string
106+ for msg , locs := range errCounts {
107+ parts = append (parts , fmt .Sprintf ("%s: %s" , strings .Join (locs , ", " ), msg ))
108+ }
109+ return fmt .Errorf ("failed to list from all locations:\n %s" , strings .Join (parts , "\n " ))
110+ }
111+
112+ // Partial failure — warn only for failed locations
113+ if len (errCounts ) > 0 {
114+ stderr := c .Command .Command .ErrOrStderr ()
115+ for msg , locs := range errCounts {
116+ fmt .Fprintf (stderr , "WARN: failed to list from %s: %s\n " , strings .Join (locs , ", " ), msg )
117+ }
90118 }
91119
92120 // Determine output format
0 commit comments