fix the file/line output on panic recovery (#3190)

#### Does this PR need a docs update or release note?

- [x]  No

#### Type of change

- [x] 🐛 Bugfix

#### Test Plan

- [x] 💪 Manual
- [x]  Unit test
This commit is contained in:
Keepers 2023-04-21 09:53:10 -06:00 committed by GitHub
parent a4c1bd9db7
commit 897c0f8a07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 40 additions and 24 deletions

View File

@ -5,6 +5,7 @@ import (
"fmt"
"runtime"
"runtime/debug"
"strings"
"github.com/alcionai/clues"
@ -22,31 +23,46 @@ import (
// err = crErr // err needs to be a named return variable
// }
// }()
func Recovery(ctx context.Context, r any) error {
func Recovery(ctx context.Context, r any, namespace string) error {
var (
err error
inFile string
j int
)
if r != nil {
if re, ok := r.(error); ok {
err = re
} else if re, ok := r.(string); ok {
err = clues.New(re)
} else {
err = clues.New(fmt.Sprintf("%v", r))
}
_, file, _, ok := runtime.Caller(3)
if ok {
inFile = " in file: " + file
}
err = clues.Wrap(err, "panic recovery"+inFile).
WithClues(ctx).
With("stacktrace", string(debug.Stack()))
logger.CtxErr(ctx, err).Error("backup panic")
if r == nil {
return nil
}
if re, ok := r.(error); ok {
err = re
} else if re, ok := r.(string); ok {
err = clues.New(re)
} else {
err = clues.New(fmt.Sprintf("%v", r))
}
for i := 1; i < 10; i++ {
_, file, line, ok := runtime.Caller(i)
if j > 0 {
if strings.Contains(file, "panic.go") {
j = 0
} else {
inFile = fmt.Sprintf(": file %s - line %d", file, line)
break
}
}
// skip the location where Recovery() gets called.
if j == 0 && ok && !strings.Contains(file, "panic.go") && !strings.Contains(file, "crash.go") {
j++
}
}
err = clues.Wrap(err, "panic recovery"+inFile).
WithClues(ctx).
With("stacktrace", string(debug.Stack()))
logger.CtxErr(ctx, err).Error(namespace + " panic")
return err
}

View File

@ -52,7 +52,7 @@ func (suite *CrashTestDummySuite) TestRecovery() {
ctx, flush := tester.NewContext()
defer func() {
err := crash.Recovery(ctx, recover())
err := crash.Recovery(ctx, recover(), "test")
test.expect(t, err, clues.ToCore(err))
flush()
}()

View File

@ -115,7 +115,7 @@ type backupStats struct {
// Run begins a synchronous backup operation.
func (op *BackupOperation) Run(ctx context.Context) (err error) {
defer func() {
if crErr := crash.Recovery(ctx, recover()); crErr != nil {
if crErr := crash.Recovery(ctx, recover(), "backup"); crErr != nil {
err = crErr
}
}()

View File

@ -104,7 +104,7 @@ type restoreStats struct {
// Run begins a synchronous restore operation.
func (op *RestoreOperation) Run(ctx context.Context) (restoreDetails *details.Details, err error) {
defer func() {
if crErr := crash.Recovery(ctx, recover()); crErr != nil {
if crErr := crash.Recovery(ctx, recover(), "restore"); crErr != nil {
err = crErr
}
}()

View File

@ -115,7 +115,7 @@ func Initialize(
"storage_provider", s.Provider.String())
defer func() {
if crErr := crash.Recovery(ctx, recover()); crErr != nil {
if crErr := crash.Recovery(ctx, recover(), "repo init"); crErr != nil {
err = crErr
}
}()
@ -189,7 +189,7 @@ func Connect(
"storage_provider", s.Provider.String())
defer func() {
if crErr := crash.Recovery(ctx, recover()); crErr != nil {
if crErr := crash.Recovery(ctx, recover(), "repo connect"); crErr != nil {
err = crErr
}
}()