diff --git a/codeagent-wrapper/logger.go b/codeagent-wrapper/logger.go index a4da52e..f33299e 100644 --- a/codeagent-wrapper/logger.go +++ b/codeagent-wrapper/logger.go @@ -170,6 +170,36 @@ func (l *Logger) RemoveLogFile() error { return os.Remove(l.path) } +// ExtractRecentErrors reads the log file and returns the most recent ERROR and WARN entries. +// Returns up to maxEntries entries in chronological order. +func (l *Logger) ExtractRecentErrors(maxEntries int) []string { + if l == nil || l.path == "" { + return nil + } + + f, err := os.Open(l.path) + if err != nil { + return nil + } + defer f.Close() + + var entries []string + scanner := bufio.NewScanner(f) + for scanner.Scan() { + line := scanner.Text() + if strings.Contains(line, "] ERROR:") || strings.Contains(line, "] WARN:") { + entries = append(entries, line) + } + } + + // Keep only the last maxEntries + if len(entries) > maxEntries { + entries = entries[len(entries)-maxEntries:] + } + + return entries +} + // Flush waits for all pending log entries to be written. Primarily for tests. // Returns after a 5-second timeout to prevent indefinite blocking. func (l *Logger) Flush() { diff --git a/codeagent-wrapper/main.go b/codeagent-wrapper/main.go index e81f333..814250f 100644 --- a/codeagent-wrapper/main.go +++ b/codeagent-wrapper/main.go @@ -141,8 +141,17 @@ func run() (exitCode int) { if err := closeLogger(); err != nil { fmt.Fprintf(os.Stderr, "ERROR: failed to close logger: %v\n", err) } - // Always remove log file after completion + // On failure, extract and display recent errors before removing log if logger != nil { + if exitCode != 0 { + if errors := logger.ExtractRecentErrors(10); len(errors) > 0 { + fmt.Fprintln(os.Stderr, "\n=== Recent Errors ===") + for _, entry := range errors { + fmt.Fprintln(os.Stderr, entry) + } + fmt.Fprintf(os.Stderr, "Log file: %s (deleted)\n", logger.Path()) + } + } if err := logger.RemoveLogFile(); err != nil && !os.IsNotExist(err) { // Silently ignore removal errors }