@@ -2,52 +2,28 @@ package errors
2
2
3
3
import (
4
4
"bytes"
5
- "embed "
5
+ "cmp "
6
6
"errors"
7
7
"fmt"
8
8
"regexp"
9
9
"strings"
10
10
11
- "github.com/alecthomas/chroma/v2"
12
- "github.com/alecthomas/chroma/v2/quick"
13
- "github.com/alecthomas/chroma/v2/styles"
14
11
"github.com/fatih/color"
15
12
"gopkg.in/yaml.v3"
16
13
)
17
14
18
- //go:embed themes/*.xml
19
- var embedded embed.FS
20
-
21
15
var typeErrorRegex = regexp .MustCompile (`line \d+: (.*)` )
22
16
23
- func init () {
24
- r , err := embedded .Open ("themes/task.xml" )
25
- if err != nil {
26
- panic (err )
27
- }
28
- style , err := chroma .NewXMLStyle (r )
29
- if err != nil {
30
- panic (err )
31
- }
32
- styles .Register (style )
33
- }
34
-
35
17
type (
36
18
TaskfileDecodeError struct {
37
19
Message string
38
20
Location string
39
21
Line int
40
22
Column int
41
23
Tag string
42
- Snippet TaskfileSnippet
24
+ Snippet string
43
25
Err error
44
26
}
45
- TaskfileSnippet struct {
46
- Lines []string
47
- StartLine int
48
- EndLine int
49
- Padding int
50
- }
51
27
)
52
28
53
29
func NewTaskfileDecodeError (err error , node * yaml.Node ) * TaskfileDecodeError {
@@ -88,38 +64,44 @@ func (err *TaskfileDecodeError) Error() string {
88
64
}
89
65
}
90
66
fmt .Fprintln (buf , color .RedString ("file: %s:%d:%d" , err .Location , err .Line , err .Column ))
67
+ fmt .Fprint (buf , err .Snippet )
68
+ return buf .String ()
69
+ }
91
70
92
- // Print the snippet
93
- maxLineNumberDigits := digits (err .Snippet .EndLine )
94
- lineNumberSpacer := strings .Repeat (" " , maxLineNumberDigits )
95
- columnSpacer := strings .Repeat (" " , err .Column - 1 )
96
- for i , line := range err .Snippet .Lines {
97
- currentLine := err .Snippet .StartLine + i + 1
71
+ func (err * TaskfileDecodeError ) Debug () string {
72
+ const indentWidth = 2
73
+ buf := & bytes.Buffer {}
74
+ fmt .Fprintln (buf , "TaskfileDecodeError:" )
98
75
99
- lineIndicator := " "
100
- if currentLine == err .Line {
101
- lineIndicator = ">"
102
- }
103
- columnIndicator := "^"
104
-
105
- // Print each line
106
- lineIndicator = color .RedString (lineIndicator )
107
- columnIndicator = color .RedString (columnIndicator )
108
- lineNumberFormat := fmt .Sprintf ("%%%dd" , maxLineNumberDigits )
109
- lineNumber := fmt .Sprintf (lineNumberFormat , currentLine )
110
- fmt .Fprintf (buf , "%s %s | %s" , lineIndicator , lineNumber , line )
111
-
112
- // Print the column indicator
113
- if currentLine == err .Line {
114
- fmt .Fprintf (buf , "\n %s | %s%s" , lineNumberSpacer , columnSpacer , columnIndicator )
76
+ // Recursively loop through the error chain and print any details
77
+ var debug func (error , int )
78
+ debug = func (err error , indent int ) {
79
+ indentStr := strings .Repeat (" " , indent * indentWidth )
80
+
81
+ // Nothing left to unwrap
82
+ if err == nil {
83
+ fmt .Fprintf (buf , "%sEnd of chain\n " , indentStr )
84
+ return
115
85
}
116
86
117
- // If there are more lines to print, add a newline
118
- if i < len (err .Snippet .Lines )- 1 {
119
- fmt .Fprintln (buf )
87
+ // Taskfile decode error
88
+ decodeErr := & TaskfileDecodeError {}
89
+ if errors .As (err , & decodeErr ) {
90
+ fmt .Fprintf (buf , "%s%s (%s:%d:%d)\n " ,
91
+ indentStr ,
92
+ cmp .Or (decodeErr .Message , "<no_message>" ),
93
+ decodeErr .Location ,
94
+ decodeErr .Line ,
95
+ decodeErr .Column ,
96
+ )
97
+ debug (errors .Unwrap (err ), indent + 1 )
98
+ return
120
99
}
121
- }
122
100
101
+ fmt .Fprintf (buf , "%s%s\n " , indentStr , err )
102
+ debug (errors .Unwrap (err ), indent + 1 )
103
+ }
104
+ debug (err , 0 )
123
105
return buf .String ()
124
106
}
125
107
@@ -141,23 +123,9 @@ func (err *TaskfileDecodeError) WithTypeMessage(t string) *TaskfileDecodeError {
141
123
return err
142
124
}
143
125
144
- func (err * TaskfileDecodeError ) WithFileInfo (location string , b []byte , padding int ) * TaskfileDecodeError {
145
- buf := & bytes.Buffer {}
146
- if err := quick .Highlight (buf , string (b ), "yaml" , "terminal" , "task" ); err != nil {
147
- buf .WriteString (string (b ))
148
- }
149
- lines := strings .Split (buf .String (), "\n " )
150
- start := max (err .Line - 1 - padding , 0 )
151
- end := min (err .Line + padding , len (lines )- 1 )
152
-
126
+ func (err * TaskfileDecodeError ) WithFileInfo (location string , snippet string ) * TaskfileDecodeError {
153
127
err .Location = location
154
- err .Snippet = TaskfileSnippet {
155
- Lines : lines [start :end ],
156
- StartLine : start ,
157
- EndLine : end ,
158
- Padding : padding ,
159
- }
160
-
128
+ err .Snippet = snippet
161
129
return err
162
130
}
163
131
@@ -168,12 +136,3 @@ func extractTypeErrorMessage(message string) string {
168
136
}
169
137
return message
170
138
}
171
-
172
- func digits (number int ) int {
173
- count := 0
174
- for number != 0 {
175
- number /= 10
176
- count += 1
177
- }
178
- return count
179
- }
0 commit comments