--- /dev/null
+package errors
+
+import (
+ "fmt"
+ "runtime"
+)
+
+const stackTraceSize = 10
+
+// StackFrame represents a single entry in a stack trace.
+type StackFrame struct {
+ Func string
+ File string
+ Line int
+}
+
+// String satisfies the fmt.Stringer interface.
+func (f StackFrame) String() string {
+ return fmt.Sprintf("%s:%d - %s", f.File, f.Line, f.Func)
+}
+
+// Stack returns the stack trace of an error. The error must contain the stack
+// trace, or wrap an error that has a stack trace,
+func Stack(err error) []StackFrame {
+ if wErr, ok := err.(wrapperError); ok {
+ return wErr.stack
+ }
+ return nil
+}
+
+// getStack is a formatting wrapper around runtime.Callers. It returns a stack
+// trace in the form of a StackFrame slice.
+func getStack(skip int, size int) []StackFrame {
+ var (
+ pc = make([]uintptr, size)
+ calls = runtime.Callers(skip+1, pc)
+ trace []StackFrame
+ )
+
+ for i := 0; i < calls; i++ {
+ f := runtime.FuncForPC(pc[i])
+ file, line := f.FileLine(pc[i] - 1)
+ trace = append(trace, StackFrame{
+ Func: f.Name(),
+ File: file,
+ Line: line,
+ })
+ }
+
+ return trace
+}