Skip to content

Commit 6a7bbcc

Browse files
authored
Create new errors in proc.go using errors module. (#526)
Start using new errors to unify error messages, complete with groundwork for wrapping errors once Go v1.20+ is the default Signed-off-by: Conall O'Brien <[email protected]>
1 parent dd377c7 commit 6a7bbcc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+195
-183
lines changed

arp.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ type ARPEntry struct {
5555
func (fs FS) GatherARPEntries() ([]ARPEntry, error) {
5656
data, err := os.ReadFile(fs.proc.Path("net/arp"))
5757
if err != nil {
58-
return nil, fmt.Errorf("error reading arp %q: %w", fs.proc.Path("net/arp"), err)
58+
return nil, fmt.Errorf("%s: error reading arp %s: %w", ErrFileRead, fs.proc.Path("net/arp"), err)
5959
}
6060

6161
return parseARPEntries(data)
@@ -78,11 +78,11 @@ func parseARPEntries(data []byte) ([]ARPEntry, error) {
7878
} else if width == expectedDataWidth {
7979
entry, err := parseARPEntry(columns)
8080
if err != nil {
81-
return []ARPEntry{}, fmt.Errorf("failed to parse ARP entry: %w", err)
81+
return []ARPEntry{}, fmt.Errorf("%s: Failed to parse ARP entry: %v: %w", ErrFileParse, entry, err)
8282
}
8383
entries = append(entries, entry)
8484
} else {
85-
return []ARPEntry{}, fmt.Errorf("%d columns were detected, but %d were expected", width, expectedDataWidth)
85+
return []ARPEntry{}, fmt.Errorf("%s: %d columns found, but expected %d: %w", ErrFileParse, width, expectedDataWidth, err)
8686
}
8787

8888
}

buddyinfo.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) {
5555
parts := strings.Fields(line)
5656

5757
if len(parts) < 4 {
58-
return nil, fmt.Errorf("invalid number of fields when parsing buddyinfo")
58+
return nil, fmt.Errorf("%w: Invalid number of fields, found: %v", ErrFileParse, parts)
5959
}
6060

6161
node := strings.TrimRight(parts[1], ",")
@@ -66,15 +66,15 @@ func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) {
6666
bucketCount = arraySize
6767
} else {
6868
if bucketCount != arraySize {
69-
return nil, fmt.Errorf("mismatch in number of buddyinfo buckets, previous count %d, new count %d", bucketCount, arraySize)
69+
return nil, fmt.Errorf("%w: mismatch in number of buddyinfo buckets, previous count %d, new count %d", ErrFileParse, bucketCount, arraySize)
7070
}
7171
}
7272

7373
sizes := make([]float64, arraySize)
7474
for i := 0; i < arraySize; i++ {
7575
sizes[i], err = strconv.ParseFloat(parts[i+4], 64)
7676
if err != nil {
77-
return nil, fmt.Errorf("invalid value in buddyinfo: %w", err)
77+
return nil, fmt.Errorf("%s: Invalid valid in buddyinfo: %f: %w", ErrFileParse, sizes[i], err)
7878
}
7979
}
8080

buddyinfo_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ Node 0, zone
5252
if err == nil {
5353
t.Fatalf("expected error, but none occurred")
5454
}
55-
if want, got := "invalid number of fields when parsing buddyinfo", err.Error(); want != got {
56-
t.Fatalf("wrong error returned, wanted %q, got %q", want, got)
55+
if want, got := "Error Parsing File: Invalid number of fields, found: [Node 0, zone]", err.Error(); want != got {
56+
t.Fatalf("Error Parsing File: Invalid number of fields, found: [Node %q, %q]", want, got)
5757
}
5858
}
5959

@@ -68,7 +68,7 @@ Node 0, zone Normal 4381 1093 185 1530 567 102 4 0
6868
if err == nil {
6969
t.Fatalf("expected error, but none occurred")
7070
}
71-
if want, got := "mismatch in number of buddyinfo buckets", err.Error(); !strings.HasPrefix(got, want) {
72-
t.Fatalf("wrong error returned, wanted prefix %q, got %q", want, got)
71+
if want, got := "Error Parsing File: mismatch in number of buddyinfo buckets, previous count 11, new count 12", err.Error(); !strings.HasPrefix(got, want) {
72+
t.Fatalf("Error Parsing File: mismatch in number of buddyinfo buckets, previous count %q, new count %q", want, got)
7373
}
7474
}

cpuinfo.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func parseCPUInfoX86(info []byte) ([]CPUInfo, error) {
7979
// find the first "processor" line
8080
firstLine := firstNonEmptyLine(scanner)
8181
if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") {
82-
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
82+
return nil, fmt.Errorf("%w: Cannot parse line: %q", ErrFileParse, firstLine)
8383
}
8484
field := strings.SplitN(firstLine, ": ", 2)
8585
v, err := strconv.ParseUint(field[1], 0, 32)
@@ -192,9 +192,10 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) {
192192
scanner := bufio.NewScanner(bytes.NewReader(info))
193193

194194
firstLine := firstNonEmptyLine(scanner)
195-
match, _ := regexp.MatchString("^[Pp]rocessor", firstLine)
195+
match, err := regexp.MatchString("^[Pp]rocessor", firstLine)
196196
if !match || !strings.Contains(firstLine, ":") {
197-
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
197+
return nil, fmt.Errorf("%s: Cannot parse line: %q: %w", ErrFileParse, firstLine, err)
198+
198199
}
199200
field := strings.SplitN(firstLine, ": ", 2)
200201
cpuinfo := []CPUInfo{}
@@ -258,7 +259,7 @@ func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) {
258259

259260
firstLine := firstNonEmptyLine(scanner)
260261
if !strings.HasPrefix(firstLine, "vendor_id") || !strings.Contains(firstLine, ":") {
261-
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
262+
return nil, fmt.Errorf("%w: Cannot parse line: %q", ErrFileParse, firstLine)
262263
}
263264
field := strings.SplitN(firstLine, ": ", 2)
264265
cpuinfo := []CPUInfo{}
@@ -283,7 +284,7 @@ func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) {
283284
if strings.HasPrefix(line, "processor") {
284285
match := cpuinfoS390XProcessorRegexp.FindStringSubmatch(line)
285286
if len(match) < 2 {
286-
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
287+
return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine)
287288
}
288289
cpu := commonCPUInfo
289290
v, err := strconv.ParseUint(match[1], 0, 32)
@@ -343,7 +344,7 @@ func parseCPUInfoMips(info []byte) ([]CPUInfo, error) {
343344
// find the first "processor" line
344345
firstLine := firstNonEmptyLine(scanner)
345346
if !strings.HasPrefix(firstLine, "system type") || !strings.Contains(firstLine, ":") {
346-
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
347+
return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine)
347348
}
348349
field := strings.SplitN(firstLine, ": ", 2)
349350
cpuinfo := []CPUInfo{}
@@ -421,7 +422,7 @@ func parseCPUInfoPPC(info []byte) ([]CPUInfo, error) {
421422

422423
firstLine := firstNonEmptyLine(scanner)
423424
if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") {
424-
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
425+
return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine)
425426
}
426427
field := strings.SplitN(firstLine, ": ", 2)
427428
v, err := strconv.ParseUint(field[1], 0, 32)
@@ -466,7 +467,7 @@ func parseCPUInfoRISCV(info []byte) ([]CPUInfo, error) {
466467

467468
firstLine := firstNonEmptyLine(scanner)
468469
if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") {
469-
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
470+
return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine)
470471
}
471472
field := strings.SplitN(firstLine, ": ", 2)
472473
v, err := strconv.ParseUint(field[1], 0, 32)

crypto.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,13 @@ func (fs FS) Crypto() ([]Crypto, error) {
5555
path := fs.proc.Path("crypto")
5656
b, err := util.ReadFileNoStat(path)
5757
if err != nil {
58-
return nil, fmt.Errorf("error reading crypto %q: %w", path, err)
58+
return nil, fmt.Errorf("%s: Cannot read file %v: %w", ErrFileRead, b, err)
59+
5960
}
6061

6162
crypto, err := parseCrypto(bytes.NewReader(b))
6263
if err != nil {
63-
return nil, fmt.Errorf("error parsing crypto %q: %w", path, err)
64+
return nil, fmt.Errorf("%s: Cannot parse %v: %w", ErrFileParse, crypto, err)
6465
}
6566

6667
return crypto, nil
@@ -83,7 +84,7 @@ func parseCrypto(r io.Reader) ([]Crypto, error) {
8384

8485
kv := strings.Split(text, ":")
8586
if len(kv) != 2 {
86-
return nil, fmt.Errorf("malformed crypto line: %q", text)
87+
return nil, fmt.Errorf("%w: Cannot parae line: %q", ErrFileParse, text)
8788
}
8889

8990
k := strings.TrimSpace(kv[0])

fscache.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ func (fs FS) Fscacheinfo() (Fscacheinfo, error) {
236236

237237
m, err := parseFscacheinfo(bytes.NewReader(b))
238238
if err != nil {
239-
return Fscacheinfo{}, fmt.Errorf("failed to parse Fscacheinfo: %w", err)
239+
return Fscacheinfo{}, fmt.Errorf("%s: Cannot parse %v: %w", ErrFileParse, m, err)
240240
}
241241

242242
return *m, nil
@@ -245,7 +245,7 @@ func (fs FS) Fscacheinfo() (Fscacheinfo, error) {
245245
func setFSCacheFields(fields []string, setFields ...*uint64) error {
246246
var err error
247247
if len(fields) < len(setFields) {
248-
return fmt.Errorf("Insufficient number of fields, expected %v, got %v", len(setFields), len(fields))
248+
return fmt.Errorf("%s: Expected %d, but got %d: %w", ErrFileParse, len(setFields), len(fields), err)
249249
}
250250

251251
for i := range setFields {
@@ -263,7 +263,7 @@ func parseFscacheinfo(r io.Reader) (*Fscacheinfo, error) {
263263
for s.Scan() {
264264
fields := strings.Fields(s.Text())
265265
if len(fields) < 2 {
266-
return nil, fmt.Errorf("malformed Fscacheinfo line: %q", s.Text())
266+
return nil, fmt.Errorf("%w: malformed Fscacheinfo line: %q", ErrFileParse, s.Text())
267267
}
268268

269269
switch fields[0] {

ipvs.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -221,15 +221,16 @@ func parseIPPort(s string) (net.IP, uint16, error) {
221221
case 46:
222222
ip = net.ParseIP(s[1:40])
223223
if ip == nil {
224-
return nil, 0, fmt.Errorf("invalid IPv6 address: %s", s[1:40])
224+
return nil, 0, fmt.Errorf("%s: Invalid IPv6 addr %s: %w", ErrFileParse, s[1:40], err)
225225
}
226226
default:
227-
return nil, 0, fmt.Errorf("unexpected IP:Port: %s", s)
227+
return nil, 0, fmt.Errorf("%s: Unexpected IP:Port %s: %w", ErrFileParse, s, err)
228228
}
229229

230230
portString := s[len(s)-4:]
231231
if len(portString) != 4 {
232-
return nil, 0, fmt.Errorf("unexpected port string format: %s", portString)
232+
return nil, 0,
233+
fmt.Errorf("%s: Unexpected port string format %s: %w", ErrFileParse, portString, err)
233234
}
234235
port, err := strconv.ParseUint(portString, 16, 16)
235236
if err != nil {

loadavg.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ func parseLoad(loadavgBytes []byte) (*LoadAvg, error) {
4444
loads := make([]float64, 3)
4545
parts := strings.Fields(string(loadavgBytes))
4646
if len(parts) < 3 {
47-
return nil, fmt.Errorf("malformed loadavg line: too few fields in loadavg string: %q", string(loadavgBytes))
47+
return nil, fmt.Errorf("%w: Malformed line %q", ErrFileParse, string(loadavgBytes))
4848
}
4949

5050
var err error
5151
for i, load := range parts[0:3] {
5252
loads[i], err = strconv.ParseFloat(load, 64)
5353
if err != nil {
54-
return nil, fmt.Errorf("could not parse load %q: %w", load, err)
54+
return nil, fmt.Errorf("%s: Cannot parse load: %f: %w", ErrFileParse, loads[i], err)
5555
}
5656
}
5757
return &LoadAvg{

mdstat.go

+18-18
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (fs FS) MDStat() ([]MDStat, error) {
7070
}
7171
mdstat, err := parseMDStat(data)
7272
if err != nil {
73-
return nil, fmt.Errorf("error parsing mdstat %q: %w", fs.proc.Path("mdstat"), err)
73+
return nil, fmt.Errorf("%s: Cannot parse %v: %w", ErrFileParse, fs.proc.Path("mdstat"), err)
7474
}
7575
return mdstat, nil
7676
}
@@ -90,13 +90,13 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) {
9090

9191
deviceFields := strings.Fields(line)
9292
if len(deviceFields) < 3 {
93-
return nil, fmt.Errorf("not enough fields in mdline (expected at least 3): %s", line)
93+
return nil, fmt.Errorf("%s: Expected 3+ lines, got %q", ErrFileParse, line)
9494
}
9595
mdName := deviceFields[0] // mdx
9696
state := deviceFields[2] // active or inactive
9797

9898
if len(lines) <= i+3 {
99-
return nil, fmt.Errorf("error parsing %q: too few lines for md device", mdName)
99+
return nil, fmt.Errorf("%w: Too few lines for md device: %q", ErrFileParse, mdName)
100100
}
101101

102102
// Failed disks have the suffix (F) & Spare disks have the suffix (S).
@@ -105,7 +105,7 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) {
105105
active, total, down, size, err := evalStatusLine(lines[i], lines[i+1])
106106

107107
if err != nil {
108-
return nil, fmt.Errorf("error parsing md device lines: %w", err)
108+
return nil, fmt.Errorf("%s: Cannot parse md device lines: %v: %w", ErrFileParse, active, err)
109109
}
110110

111111
syncLineIdx := i + 2
@@ -140,7 +140,7 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) {
140140
} else {
141141
syncedBlocks, pct, finish, speed, err = evalRecoveryLine(lines[syncLineIdx])
142142
if err != nil {
143-
return nil, fmt.Errorf("error parsing sync line in md device %q: %w", mdName, err)
143+
return nil, fmt.Errorf("%s: Cannot parse sync line in md device: %q: %w", ErrFileParse, mdName, err)
144144
}
145145
}
146146
}
@@ -168,13 +168,13 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) {
168168
func evalStatusLine(deviceLine, statusLine string) (active, total, down, size int64, err error) {
169169
statusFields := strings.Fields(statusLine)
170170
if len(statusFields) < 1 {
171-
return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q", statusLine)
171+
return 0, 0, 0, 0, fmt.Errorf("%s: Unexpected statusline %q: %w", ErrFileParse, statusLine, err)
172172
}
173173

174174
sizeStr := statusFields[0]
175175
size, err = strconv.ParseInt(sizeStr, 10, 64)
176176
if err != nil {
177-
return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err)
177+
return 0, 0, 0, 0, fmt.Errorf("%s: Unexpected statusline %q: %w", ErrFileParse, statusLine, err)
178178
}
179179

180180
if strings.Contains(deviceLine, "raid0") || strings.Contains(deviceLine, "linear") {
@@ -189,17 +189,17 @@ func evalStatusLine(deviceLine, statusLine string) (active, total, down, size in
189189

190190
matches := statusLineRE.FindStringSubmatch(statusLine)
191191
if len(matches) != 5 {
192-
return 0, 0, 0, 0, fmt.Errorf("couldn't find all the substring matches: %s", statusLine)
192+
return 0, 0, 0, 0, fmt.Errorf("%s: Could not fild all substring matches %s: %w", ErrFileParse, statusLine, err)
193193
}
194194

195195
total, err = strconv.ParseInt(matches[2], 10, 64)
196196
if err != nil {
197-
return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err)
197+
return 0, 0, 0, 0, fmt.Errorf("%s: Unexpected statusline %q: %w", ErrFileParse, statusLine, err)
198198
}
199199

200200
active, err = strconv.ParseInt(matches[3], 10, 64)
201201
if err != nil {
202-
return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err)
202+
return 0, 0, 0, 0, fmt.Errorf("%s: Unexpected active %d: %w", ErrFileParse, active, err)
203203
}
204204
down = int64(strings.Count(matches[4], "_"))
205205

@@ -209,42 +209,42 @@ func evalStatusLine(deviceLine, statusLine string) (active, total, down, size in
209209
func evalRecoveryLine(recoveryLine string) (syncedBlocks int64, pct float64, finish float64, speed float64, err error) {
210210
matches := recoveryLineBlocksRE.FindStringSubmatch(recoveryLine)
211211
if len(matches) != 2 {
212-
return 0, 0, 0, 0, fmt.Errorf("unexpected recoveryLine: %s", recoveryLine)
212+
return 0, 0, 0, 0, fmt.Errorf("%s: Unexpected recoveryLine %s: %w", ErrFileParse, recoveryLine, err)
213213
}
214214

215215
syncedBlocks, err = strconv.ParseInt(matches[1], 10, 64)
216216
if err != nil {
217-
return 0, 0, 0, 0, fmt.Errorf("error parsing int from recoveryLine %q: %w", recoveryLine, err)
217+
return 0, 0, 0, 0, fmt.Errorf("%s: Unexpected parsing of recoveryLine %q: %w", ErrFileParse, recoveryLine, err)
218218
}
219219

220220
// Get percentage complete
221221
matches = recoveryLinePctRE.FindStringSubmatch(recoveryLine)
222222
if len(matches) != 2 {
223-
return syncedBlocks, 0, 0, 0, fmt.Errorf("unexpected recoveryLine matching percentage: %s", recoveryLine)
223+
return syncedBlocks, 0, 0, 0, fmt.Errorf("%w: Unexpected recoveryLine matching percentage %s", ErrFileParse, recoveryLine)
224224
}
225225
pct, err = strconv.ParseFloat(strings.TrimSpace(matches[1]), 64)
226226
if err != nil {
227-
return syncedBlocks, 0, 0, 0, fmt.Errorf("error parsing float from recoveryLine %q: %w", recoveryLine, err)
227+
return syncedBlocks, 0, 0, 0, fmt.Errorf("%w: Error parsing float from recoveryLine %q", ErrFileParse, recoveryLine)
228228
}
229229

230230
// Get time expected left to complete
231231
matches = recoveryLineFinishRE.FindStringSubmatch(recoveryLine)
232232
if len(matches) != 2 {
233-
return syncedBlocks, pct, 0, 0, fmt.Errorf("unexpected recoveryLine matching est. finish time: %s", recoveryLine)
233+
return syncedBlocks, pct, 0, 0, fmt.Errorf("%w: Unexpected recoveryLine matching est. finish time: %s", ErrFileParse, recoveryLine)
234234
}
235235
finish, err = strconv.ParseFloat(matches[1], 64)
236236
if err != nil {
237-
return syncedBlocks, pct, 0, 0, fmt.Errorf("error parsing float from recoveryLine %q: %w", recoveryLine, err)
237+
return syncedBlocks, pct, 0, 0, fmt.Errorf("%w: Unable to parse float from recoveryLine: %q", ErrFileParse, recoveryLine)
238238
}
239239

240240
// Get recovery speed
241241
matches = recoveryLineSpeedRE.FindStringSubmatch(recoveryLine)
242242
if len(matches) != 2 {
243-
return syncedBlocks, pct, finish, 0, fmt.Errorf("unexpected recoveryLine matching speed: %s", recoveryLine)
243+
return syncedBlocks, pct, finish, 0, fmt.Errorf("%w: Unexpected recoveryLine value: %s", ErrFileParse, recoveryLine)
244244
}
245245
speed, err = strconv.ParseFloat(matches[1], 64)
246246
if err != nil {
247-
return syncedBlocks, pct, finish, 0, fmt.Errorf("error parsing float from recoveryLine %q: %w", recoveryLine, err)
247+
return syncedBlocks, pct, finish, 0, fmt.Errorf("%s: Error parsing float from recoveryLine: %q: %w", ErrFileParse, recoveryLine, err)
248248
}
249249

250250
return syncedBlocks, pct, finish, speed, nil

meminfo.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ func (fs FS) Meminfo() (Meminfo, error) {
152152

153153
m, err := parseMemInfo(bytes.NewReader(b))
154154
if err != nil {
155-
return Meminfo{}, fmt.Errorf("failed to parse meminfo: %w", err)
155+
return Meminfo{}, fmt.Errorf("%s: %w", ErrFileParse, err)
156156
}
157157

158158
return *m, nil
@@ -165,7 +165,7 @@ func parseMemInfo(r io.Reader) (*Meminfo, error) {
165165
// Each line has at least a name and value; we ignore the unit.
166166
fields := strings.Fields(s.Text())
167167
if len(fields) < 2 {
168-
return nil, fmt.Errorf("malformed meminfo line: %q", s.Text())
168+
return nil, fmt.Errorf("%w: Malformed line %q", ErrFileParse, s.Text())
169169
}
170170

171171
v, err := strconv.ParseUint(fields[1], 0, 64)

0 commit comments

Comments
 (0)