diff options
Diffstat (limited to 'src/urubu/error.go')
-rw-r--r-- | src/urubu/error.go | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/urubu/error.go b/src/urubu/error.go new file mode 100644 index 0000000..0e5d3af --- /dev/null +++ b/src/urubu/error.go @@ -0,0 +1,86 @@ +package error + +import ( + "bufio" + "fmt" + "os" + "sort" + "strings" +) + +type SpecErrors []*SpecError + +func (e SpecErrors) Error() string { + if len(e) == 0 { + return "" + } + + sorted := make([]*SpecError, len(e)) + copy(sorted, e) + sort.SliceStable(sorted, func(i, j int) bool { + return sorted[i].Row < sorted[j].Row + }) + sort.SliceStable(sorted, func(i, j int) bool { + return sorted[i].FilePath < sorted[j].FilePath + }) + + var b strings.Builder + fmt.Fprintf(&b, "%v", sorted[0]) + for _, err := range sorted[1:] { + fmt.Fprintf(&b, "\n%v", err) + } + + return b.String() +} + +type SpecError struct { + Cause error + Detail string + FilePath string + SourceName string + Row int + Col int +} + +func (e *SpecError) Error() string { + var b strings.Builder + if e.SourceName != "" { + fmt.Fprintf(&b, "%v: ", e.SourceName) + } + if e.Row != 0 && e.Col != 0 { + fmt.Fprintf(&b, "%v:%v: ", e.Row, e.Col) + } + fmt.Fprintf(&b, "error: %v", e.Cause) + if e.Detail != "" { + fmt.Fprintf(&b, ": %v", e.Detail) + } + + line := readLine(e.FilePath, e.Row) + if line != "" { + fmt.Fprintf(&b, "\n %v", line) + } + + return b.String() +} + +func readLine(filePath string, row int) string { + if filePath == "" || row <= 0 { + return "" + } + + f, err := os.Open(filePath) + if err != nil { + return "" + } + + i := 1 + s := bufio.NewScanner(f) + for s.Scan() { + if i == row { + return s.Text() + } + i++ + } + + return "" +} |