Errors
package revel
type Error struct {
SourceType string
Title, Path, Description string
Line, Column int
SourceLines []string
Stack string
MetaError string
}
func NewErrorFromPanic(err interface{}) *Error {
stack := string(debug.Stack())
frame, basePath := findRelevantStackFrame(stack)
if frame == -1 {
return nil
}
stack = stack[frame:]
stackElement := stack[:strings.Index(stack, "\n")]
colonIndex := strings.LastIndex(stackElement, ":")
filename := stackElement[:colonIndex]
var line int
fmt.Sscan(stackElement[colonIndex+1:], &line)
description := "Unspecified error"
if err != nil {
description = fmt.Sprint(err)
}
return &Error{
Title: "Panic",
Path: filename[len(basePath):],
Line: line,
Description: description,
SourceLines: MustReadLines(filename),
Stack: stack,
}
}
func (e *Error) Error() string {
loc := ""
if e.Path != "" {
line := ""
if e.Line != 0 {
line = fmt.Sprintf(":%d", e.Line)
}
loc = fmt.Sprintf("(in %s%s)", e.Path, line)
}
header := loc
if e.Title != "" {
if loc != "" {
header = fmt.Sprintf("%s %s: ", e.Title, loc)
} else {
header = fmt.Sprintf("%s: ", e.Title)
}
}
return fmt.Sprintf("%s%s", header, e.Description)
}
func (e *Error) ContextSource() []sourceLine {
if e.SourceLines == nil {
return nil
}
start := (e.Line - 1) - 5
if start < 0 {
start = 0
}
end := (e.Line - 1) + 5
if end > len(e.SourceLines) {
end = len(e.SourceLines)
}
var lines []sourceLine = make([]sourceLine, end-start)
for i, src := range e.SourceLines[start:end] {
fileLine := start + i + 1
lines[i] = sourceLine{src, fileLine, fileLine == e.Line}
}
return lines
}