-
Notifications
You must be signed in to change notification settings - Fork 571
/
asynq.go
39 lines (31 loc) · 1.04 KB
/
asynq.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package utils
import (
"fmt"
"runtime/debug"
"context"
"github.com/deepfence/ThreatMapper/deepfence_utils/log"
"github.com/hibiken/asynq"
"github.com/pkg/errors"
)
type WorkerHandler func(ctx context.Context, t *asynq.Task) error
// RecoveredPanicError holds the recovered panic's error along with the stacktrace.
type RecoveredPanicError struct {
V interface{}
Stacktrace string
}
func (p RecoveredPanicError) Error() string {
return fmt.Sprintf("panic occurred: %#v, stacktrace: \n%s", p.V, p.Stacktrace)
}
// Recoverer recovers from any panic in the handler and appends RecoveredPanicError with the stacktrace
// to any error returned from the handler.
func Recoverer(h asynq.Handler) asynq.Handler {
return asynq.HandlerFunc(func(ctx context.Context, task *asynq.Task) (err error) {
defer func() {
if r := recover(); r != nil {
err = errors.WithStack(RecoveredPanicError{V: r, Stacktrace: string(debug.Stack())})
log.Error().Ctx(ctx).Err(err).Msg("recovered from panic")
}
}()
return h.ProcessTask(ctx, task)
})
}