buildlet: include details in GCEError.Error

Some of our logging in the coordinator includes pointers and repetition,
like so:

2022/09/27 19:16:27 failed with errors: [0xc02b50e120]
2022/09/27 19:16:27 Failed to create VM: "failed with errors: [0xc02b50e120]". Retrying after 1 second (attempt: 2).

The GCE error types only have MarshalJSON methods, so use that to show
more information. (This builds on the previous attempt in CL 428114.)
Remove the duplicate log, since the caller can log or otherwise handle
the error.

For golang/go#48857.

Change-Id: I0d31cac833ea617b4d722751e3ffe9a6689aeb87
Reviewed-on: https://go-review.googlesource.com/c/build/+/435379
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Jenny Rakoczy <jenny@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Dmitri Shuralyov 2022-09-27 17:08:21 -04:00 коммит произвёл Gopher Robot
Родитель cbf6b04664
Коммит 21af757eea
2 изменённых файлов: 17 добавлений и 4 удалений

Просмотреть файл

@ -5,11 +5,12 @@
package buildlet package buildlet
import ( import (
"bytes"
"context" "context"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
"log"
"net" "net"
"os" "os"
"os/exec" "os/exec"
@ -45,7 +46,20 @@ type GCEError struct {
} }
func (q *GCEError) Error() string { func (q *GCEError) Error() string {
return fmt.Sprintf("failed with errors: %+v", q.OpErrors) var buf bytes.Buffer
fmt.Fprintf(&buf, "%d GCE operation errors: ", len(q.OpErrors))
for i, e := range q.OpErrors {
if i != 0 {
buf.WriteString("; ")
}
b, err := json.Marshal(e)
if err != nil {
fmt.Fprintf(&buf, "json.Marshal(OpErrors[%d]): %v", i, err)
continue
}
buf.Write(b)
}
return buf.String()
} }
func (q *GCEError) Is(target error) bool { func (q *GCEError) Is(target error) bool {
@ -239,7 +253,6 @@ OpLoop:
if op.Error != nil { if op.Error != nil {
err := &GCEError{OpErrors: make([]*compute.OperationErrorErrors, len(op.Error.Errors))} err := &GCEError{OpErrors: make([]*compute.OperationErrorErrors, len(op.Error.Errors))}
copy(err.OpErrors, op.Error.Errors) copy(err.OpErrors, op.Error.Errors)
log.Println(err.Error())
return nil, err return nil, err
} }
break OpLoop break OpLoop

Просмотреть файл

@ -490,7 +490,7 @@ func (p *GCEBuildlet) GetBuildlet(ctx context.Context, hostType string, lg Logge
Zone: zone, Zone: zone,
}) })
if errors.Is(err, buildlet.ErrQuotaExceeded) && ctx.Err() == nil { if errors.Is(err, buildlet.ErrQuotaExceeded) && ctx.Err() == nil {
log.Printf("Failed to create VM: %q. Retrying after 1 second (attempt: %d).", err, attempts) log.Printf("Failed to create VM because quota exceeded. Retrying after 1 second (attempt: %d).", attempts)
attempts++ attempts++
time.Sleep(time.Second) time.Sleep(time.Second)
continue continue