container/vfs: wrap decoder errors
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m8s
Test / Hakurei (push) Successful in 3m15s
Test / Hpkg (push) Successful in 3m33s
Test / Sandbox (race detector) (push) Successful in 4m30s
Test / Hakurei (race detector) (push) Successful in 5m19s
Test / Flake checks (push) Successful in 1m35s

This passes line information and handles strconv errors so it reads better.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2025-08-29 21:51:31 +09:00
parent 905b9f9785
commit 50972096cd
7 changed files with 106 additions and 30 deletions

View File

@@ -24,6 +24,32 @@ var (
ErrMountInfoSep = errors.New("bad optional fields separator")
)
type DecoderError struct {
Op string
Line int
Err error
}
func (e *DecoderError) Unwrap() error { return e.Err }
func (e *DecoderError) Error() string {
var s string
var numError *strconv.NumError
switch {
case errors.As(e.Err, &numError) && numError != nil:
s = "numeric field " + strconv.Quote(numError.Num) + " " + numError.Err.Error()
default:
s = e.Err.Error()
}
var atLine string
if e.Line >= 0 {
atLine = " at line " + strconv.Itoa(e.Line)
}
return e.Op + " mountinfo" + atLine + ": " + s
}
type (
// A MountInfoDecoder reads and decodes proc_pid_mountinfo(5) entries from an input stream.
MountInfoDecoder struct {
@@ -32,6 +58,7 @@ type (
current *MountInfo
parseErr error
curLine int
complete bool
}
@@ -132,9 +159,12 @@ func (d *MountInfoDecoder) Entries() iter.Seq[*MountInfoEntry] {
func (d *MountInfoDecoder) Err() error {
if err := d.s.Err(); err != nil {
return err
return &DecoderError{"scan", d.curLine, err}
}
return d.parseErr
if d.parseErr != nil {
return &DecoderError{"parse", d.curLine, d.parseErr}
}
return nil
}
func (d *MountInfoDecoder) scan() bool {
@@ -160,6 +190,7 @@ func (d *MountInfoDecoder) scan() bool {
d.current.Next = m
d.current = d.current.Next
}
d.curLine++
return true
}