Logging: log frontend errors caught by ErrorBoundary, including component stack (#29345)

* log component stack on error boundary

* test for error boundary

* PR feedback fixes
This commit is contained in:
Domas
2020-12-10 10:50:37 +01:00
committed by GitHub
parent 4ea2c7d2b1
commit 70d68c156d
5 changed files with 81 additions and 0 deletions
+13
View File
@@ -47,6 +47,18 @@ func (exception *frontendSentryException) FmtStacktraces() string {
return strings.Join(stacktraces, "\n\n")
}
func addEventContextToLogContext(rootPrefix string, logCtx log15.Ctx, eventCtx map[string]interface{}) {
for key, element := range eventCtx {
prefix := fmt.Sprintf("%s_%s", rootPrefix, key)
switch v := element.(type) {
case map[string]interface{}:
addEventContextToLogContext(prefix, logCtx, v)
default:
logCtx[prefix] = fmt.Sprintf("%v", v)
}
}
}
func (event *frontendSentryEvent) ToLogContext() log15.Ctx {
var ctx = make(log15.Ctx)
ctx["url"] = event.Request.URL
@@ -56,6 +68,7 @@ func (event *frontendSentryEvent) ToLogContext() log15.Ctx {
if event.Exception != nil {
ctx["stacktrace"] = event.Exception.FmtStacktraces()
}
addEventContextToLogContext("context", ctx, event.Contexts)
if len(event.User.Email) > 0 {
ctx["user_email"] = event.User.Email
ctx["user_id"] = event.User.ID
+29
View File
@@ -102,6 +102,7 @@ func TestFrontendLoggingEndpoint(t *testing.T) {
assertContextContains(t, logs[0], "stacktrace", `UserError: Please replace user and try again
at foofn (foo.js:123:23)
at barfn (bar.js:113:231)`)
assert.NotContains(t, logs[0].Ctx, "context")
})
messageEvent := frontendSentryEvent{
@@ -127,9 +128,37 @@ func TestFrontendLoggingEndpoint(t *testing.T) {
assertContextContains(t, logs[0], "event_id", messageEvent.EventID)
assertContextContains(t, logs[0], "original_timestamp", messageEvent.Timestamp)
assert.NotContains(t, logs[0].Ctx, "stacktrace")
assert.NotContains(t, logs[0].Ctx, "context")
assertContextContains(t, logs[0], "user_email", user.Email)
assertContextContains(t, logs[0], "user_id", user.ID)
})
eventWithContext := frontendSentryEvent{
&sentry.Event{
EventID: "123",
Level: sentry.LevelInfo,
Request: &request,
Timestamp: ts,
Message: "hello world",
User: user,
Contexts: map[string]interface{}{
"foo": map[string]interface{}{
"one": "two",
"three": 4,
},
"bar": "baz",
},
},
nil,
}
logSentryEventScenario(t, "Should log event context", eventWithContext, func(sc *scenarioContext, logs []*log.Record) {
assert.Equal(t, 200, sc.resp.Code)
assert.Len(t, logs, 1)
assertContextContains(t, logs[0], "context_foo_one", "two")
assertContextContains(t, logs[0], "context_foo_three", "4")
assertContextContains(t, logs[0], "context_bar", "baz")
})
})
}