inancgumus/learngo · error

line %d: %v

Error message

line %d: %v

What it means

The text reader scans the input line by line and calls fastParseFields on each. When field parsing fails it stops immediately and wraps the underlying error with the 1-based line number (l), so callers know exactly which line of the file was bad. The error message is 'line %d: %v'.

Source

Thrown at logparser/functional/textreader.go:28

import (
	"bufio"
	"fmt"
	"io"
)

func textReader(r io.Reader) inputFn {
	return func(process processFn) error {
		var (
			l  = 1
			in = bufio.NewScanner(r)
		)

		for in.Scan() {
			r, err := fastParseFields(in.Bytes())
			// r, err := parseFields(in.Text())
			if err != nil {
				return fmt.Errorf("line %d: %v", l, err)
			}

			process(r)
			l++
		}

		if c, ok := r.(io.Closer); ok {
			c.Close()
		}
		return in.Err()
	}
}

View on GitHub (pinned to 3c475a78e5)

Solutions

  1. Read the line number from the error and fix that line in the log file
  2. Skip malformed lines: accumulate errors per line and continue instead of returning on the first one
  3. Make fastParseFields error messages include the raw line for easier diagnosis

Example fix

// before
if err != nil {
    return fmt.Errorf("line %d: %v", l, err)
}
// after
if err != nil {
    badLines = append(badLines, fmt.Sprintf("line %d: %v", l, err))
    continue // collect all errors instead of failing on the first
}
Defensive patterns

Strategy: validation

Validate before calling

scanner := bufio.NewScanner(f)
for scanner.Scan() {
    if len(strings.Fields(scanner.Text())) != expected {
        log.Printf("skipping line %d", l)
        continue
    }
    ...
}

Type guard

func isParsableLine(text string, want int) bool {
    return len(strings.Fields(text)) == want
}

Try / catch

if err := readLines(f, process); err != nil {
    var lineErr LineError
    if errors.As(err, &lineErr) {
        log.Printf("failed at line %d: %v", lineErr.Num, lineErr.Err)
    } else {
        return err
    }
}

Prevention

When it happens

Trigger: Reading a log file where any single line fails fastParseFields — wrong field count (error 30), or any other parse error — causes Read/process to return this wrapped error for that line number.

Common situations: Malformed line in the middle of a large log file; a different log format mixed in; a partially written last line; the file using an unexpected delimiter so fields don't split as expected.

Related errors


AI-assisted analysis of inancgumus/learngo@3c475a78e5 (2026-09-02). Data as JSON: /api/errors/f10326c04251babd. Report an issue: GitHub.