unify all panic event to panic log file (#2250)
This commit is contained in:
parent
31afad6e87
commit
e2a9bb97c7
6 changed files with 34 additions and 11 deletions
|
|
@ -991,6 +991,7 @@ func (al *AgentLoop) ReloadProviderAndConfig(
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
|
logger.RecoverPanicNoExit(r)
|
||||||
panicErr = fmt.Errorf("panic during registry creation: %v", r)
|
panicErr = fmt.Errorf("panic during registry creation: %v", r)
|
||||||
logger.ErrorCF("agent", "Panic during registry creation",
|
logger.ErrorCF("agent", "Panic during registry creation",
|
||||||
map[string]any{"panic": r})
|
map[string]any{"panic": r})
|
||||||
|
|
|
||||||
|
|
@ -427,6 +427,7 @@ func spawnSubTurn(
|
||||||
// 7. Defer cleanup: deliver result (for async), emit End event, and recover from panics
|
// 7. Defer cleanup: deliver result (for async), emit End event, and recover from panics
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
|
logger.RecoverPanicNoExit(r)
|
||||||
err = fmt.Errorf("subturn panicked: %v", r)
|
err = fmt.Errorf("subturn panicked: %v", r)
|
||||||
result = nil
|
result = nil
|
||||||
logger.ErrorCF("subturn", "SubTurn panicked", map[string]any{
|
logger.ErrorCF("subturn", "SubTurn panicked", map[string]any{
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,7 @@ func streamOggOpusToDiscord(ctx context.Context, vc *discordgo.VoiceConnection,
|
||||||
defer func() {
|
defer func() {
|
||||||
if rec := recover(); rec != nil {
|
if rec := recover(); rec != nil {
|
||||||
retErr = fmt.Errorf("voice connection closed during playback")
|
retErr = fmt.Errorf("voice connection closed during playback")
|
||||||
|
logger.RecoverPanicNoExit(rec)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,15 @@ package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var panicWriter io.WriteCloser
|
||||||
|
|
||||||
func InitPanic(filePath string) (func(), error) {
|
func InitPanic(filePath string) (func(), error) {
|
||||||
if err := os.MkdirAll(filepath.Dir(filePath), 0o755); err != nil {
|
if err := os.MkdirAll(filepath.Dir(filePath), 0o755); err != nil {
|
||||||
return nil, fmt.Errorf("failed to create log directory: %w", err)
|
return nil, fmt.Errorf("failed to create log directory: %w", err)
|
||||||
|
|
@ -16,21 +19,36 @@ func InitPanic(filePath string) (func(), error) {
|
||||||
if writer == nil {
|
if writer == nil {
|
||||||
return nil, fmt.Errorf("failed to create log file: %s", filePath)
|
return nil, fmt.Errorf("failed to create log file: %s", filePath)
|
||||||
}
|
}
|
||||||
|
if panicWriter != nil {
|
||||||
|
_ = panicWriter.Close()
|
||||||
|
}
|
||||||
|
panicWriter = writer
|
||||||
return func() {
|
return func() {
|
||||||
defer writer.Close()
|
defer func() {
|
||||||
|
writer.Close()
|
||||||
|
panicWriter = nil
|
||||||
|
}()
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
now := time.Now().Format("2006-01-02 15:04:05")
|
RecoverPanicNoExit(err)
|
||||||
stack := debug.Stack()
|
|
||||||
logMsg := "\n\n====================\n[" + now + "] PANIC OCCURRED: " + fmt.Sprintf(
|
|
||||||
"%v",
|
|
||||||
err,
|
|
||||||
) + "\n" + string(
|
|
||||||
stack,
|
|
||||||
)
|
|
||||||
|
|
||||||
writer.Write([]byte(logMsg))
|
|
||||||
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RecoverPanicNoExit(err any) {
|
||||||
|
if panicWriter == nil {
|
||||||
|
Errorf("panicWriter is nil, should not happen")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
now := time.Now().Format("2006-01-02 15:04:05")
|
||||||
|
stack := debug.Stack()
|
||||||
|
logMsg := "\n\n====================\n[" + now + "] PANIC OCCURRED: " + fmt.Sprintf(
|
||||||
|
"%v",
|
||||||
|
err,
|
||||||
|
) + "\n" + string(
|
||||||
|
stack,
|
||||||
|
)
|
||||||
|
|
||||||
|
panicWriter.Write([]byte(logMsg))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,7 @@ func (r *ToolRegistry) ExecuteWithContext(
|
||||||
func() {
|
func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if re := recover(); re != nil {
|
if re := recover(); re != nil {
|
||||||
|
logger.RecoverPanicNoExit(re)
|
||||||
errMsg := fmt.Sprintf("Tool '%s' crashed with panic: %v", name, re)
|
errMsg := fmt.Sprintf("Tool '%s' crashed with panic: %v", name, re)
|
||||||
logger.ErrorCF("tool", "Tool execution panic recovered",
|
logger.ErrorCF("tool", "Tool execution panic recovered",
|
||||||
map[string]any{
|
map[string]any{
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ func Recoverer(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
|
logger.RecoverPanicNoExit(err)
|
||||||
logger.ErrorC("http", fmt.Sprintf("panic recovered: %v\n%s", err, debug.Stack()))
|
logger.ErrorC("http", fmt.Sprintf("panic recovered: %v\n%s", err, debug.Stack()))
|
||||||
http.Error(w, `{"error":"internal server error"}`, http.StatusInternalServerError)
|
http.Error(w, `{"error":"internal server error"}`, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue