Skip to content

Commit 529be97

Browse files
authored
fix(logging): do not panic in library code (#3076)
fixes: #1862 Changes: - No longer panic on User introduced errors. Instead we log the error and let program proceed - We log.Fatalf("ptypes.TimestampProto(time.Unix(0,0)) failed: %v", err) to exit program, since it's a fatal error/likely not induced by Users
1 parent e760c85 commit 529be97

2 files changed

Lines changed: 28 additions & 19 deletions

File tree

logging/logging.go

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ import (
4747
"github.com/golang/protobuf/proto"
4848
"github.com/golang/protobuf/ptypes"
4949
structpb "github.com/golang/protobuf/ptypes/struct"
50-
tspb "github.com/golang/protobuf/ptypes/timestamp"
5150
"google.golang.org/api/option"
5251
"google.golang.org/api/support/bundler"
5352
mrpb "google.golang.org/genproto/googleapis/api/monitoredres"
@@ -174,26 +173,20 @@ func NewClient(ctx context.Context, parent string, opts ...option.ClientOption)
174173
return client, nil
175174
}
176175

177-
var unixZeroTimestamp *tspb.Timestamp
178-
179-
func init() {
180-
var err error
181-
unixZeroTimestamp, err = ptypes.TimestampProto(time.Unix(0, 0))
182-
if err != nil {
183-
panic(err)
184-
}
185-
}
186-
187176
// Ping reports whether the client's connection to the logging service and the
188177
// authentication configuration are valid. To accomplish this, Ping writes a
189178
// log entry "ping" to a log named "ping".
190179
func (c *Client) Ping(ctx context.Context) error {
180+
unixZeroTimestamp, err := ptypes.TimestampProto(time.Unix(0, 0))
181+
if err != nil {
182+
return err
183+
}
191184
ent := &logpb.LogEntry{
192185
Payload: &logpb.LogEntry_TextPayload{TextPayload: "ping"},
193186
Timestamp: unixZeroTimestamp, // Identical timestamps and insert IDs are both
194187
InsertId: "ping", // necessary for the service to dedup these entries.
195188
}
196-
_, err := c.client.WriteLogEntries(ctx, &logpb.WriteLogEntriesRequest{
189+
_, err = c.client.WriteLogEntries(ctx, &logpb.WriteLogEntriesRequest{
197190
LogName: internal.LogPath(c.parent, "ping"),
198191
Resource: monitoredResource(c.parent),
199192
Entries: []*logpb.LogEntry{ent},
@@ -695,12 +688,12 @@ type HTTPRequest struct {
695688
CacheLookup bool
696689
}
697690

698-
func fromHTTPRequest(r *HTTPRequest) *logtypepb.HttpRequest {
691+
func fromHTTPRequest(r *HTTPRequest) (*logtypepb.HttpRequest, error) {
699692
if r == nil {
700-
return nil
693+
return nil, nil
701694
}
702695
if r.Request == nil {
703-
panic("HTTPRequest must have a non-nil Request")
696+
return nil, errors.New("logging: HTTPRequest must have a non-nil Request")
704697
}
705698
u := *r.Request.URL
706699
u.Fragment = ""
@@ -723,7 +716,7 @@ func fromHTTPRequest(r *HTTPRequest) *logtypepb.HttpRequest {
723716
if r.Latency != 0 {
724717
pb.Latency = ptypes.DurationProto(r.Latency)
725718
}
726-
return pb
719+
return pb, nil
727720
}
728721

729722
// fixUTF8 is a helper that fixes an invalid UTF-8 string by replacing
@@ -803,7 +796,7 @@ func jsonValueToStructValue(v interface{}) *structpb.Value {
803796
}
804797
return &structpb.Value{Kind: &structpb.Value_ListValue{ListValue: &structpb.ListValue{Values: vals}}}
805798
default:
806-
panic(fmt.Sprintf("bad type %T for JSON value", v))
799+
return &structpb.Value{Kind: &structpb.Value_NullValue{}}
807800
}
808801
}
809802

@@ -933,11 +926,15 @@ func (l *Logger) toLogEntry(e Entry) (*logpb.LogEntry, error) {
933926
e.TraceSampled = e.TraceSampled || traceSampled
934927
}
935928
}
929+
req, err := fromHTTPRequest(e.HTTPRequest)
930+
if err != nil {
931+
l.client.error(err)
932+
}
936933
ent := &logpb.LogEntry{
937934
Timestamp: ts,
938935
Severity: logtypepb.LogSeverity(e.Severity),
939936
InsertId: e.InsertID,
940-
HttpRequest: fromHTTPRequest(e.HTTPRequest),
937+
HttpRequest: req,
941938
Operation: e.Operation,
942939
Labels: e.Labels,
943940
Trace: e.Trace,

logging/logging_unexported_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,10 @@ func TestFromHTTPRequest(t *testing.T) {
400400
CacheHit: true,
401401
CacheValidatedWithOriginServer: true,
402402
}
403-
got := fromHTTPRequest(req)
403+
got, err := fromHTTPRequest(req)
404+
if err != nil {
405+
t.Errorf("got %v", err)
406+
}
404407
want := &logtypepb.HttpRequest{
405408
RequestMethod: "GET",
406409

@@ -429,6 +432,15 @@ func TestFromHTTPRequest(t *testing.T) {
429432
if _, err := proto.Marshal(got); err != nil {
430433
t.Fatalf("Unexpected proto.Marshal error: %v", err)
431434
}
435+
436+
// fromHTTPRequest returns nil if there is no Request property (but does not panic)
437+
reqNil := &HTTPRequest{
438+
RequestSize: 100,
439+
}
440+
got, err = fromHTTPRequest(reqNil)
441+
if got != nil && err == nil {
442+
t.Errorf("got %+v\nwant %+v", got, want)
443+
}
432444
}
433445

434446
func TestMonitoredResource(t *testing.T) {

0 commit comments

Comments
 (0)