go / expert
Snippet
Strukturierte Aufrufstapel-Entfaltung und Frame-Extraktion bei Deferred-Recover
Die Kombination von deferred recover() mit runtime.Callers und runtime.CallersFrames ermöglicht es Panic-Wrappern, programmatische Stack-Frame-Details (Dateipfade, Zeilennummern, Funktionsnamen) zu extrahieren, anstatt sich auf formatierte Stack-String-Dumps zu verlassen, was eine strukturierte Fehlerbehandlung erlaubt.
snippet.go
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
40
41
42
43
44
45
46
47
48
49
50
package mainimport ("fmt""runtime")type StackFrame struct {Function stringFile stringLine int}func captureStackTrace(skip int) []StackFrame {pcs := make([]uintptr, 10)n := runtime.Callers(skip, pcs)frames := runtime.CallersFrames(pcs[:n])var result []StackFramefor {frame, more := frames.Next()result = append(result, StackFrame{Function: frame.Function,File: frame.File,Line: frame.Line,})if !more {break}}return result}func safeExecute(fn func()) (err error) {defer func() {if r := recover(); r != nil {frames := captureStackTrace(3)err = fmt.Errorf("panic recovered: %v | origin: %s:%d", r, frames[0].File, frames[0].Line)}}()fn()return nil}func main() {err := safeExecute(func() {panic("critical operational failure")})fmt.Println(err)}
Erklärung
1
n := runtime.Callers(skip, pcs)
Füllt Programmzähler-Ausführungsadressen unter Überspringen von Overhead in das Ziel-Slice.
2
frames := runtime.CallersFrames(pcs[:n])
Dekodiert Programmzähler in lesbare Quellcode-Symbole und Standortstrukturen.