Маленькая утилита на database/sql вернула половину списка. Без ошибки. Код такой.
func names(ctx context.Context, db *sql.DB) ([]string, error) {
rows, err := db.QueryContext(ctx, `SELECT name FROM users ORDER BY id`)
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
if err != nil {
return nil, fmt.Errorf("users: %w", err)
}
defer rows.Close()
var out []string
for rows.Next() {
var n string
if err := rows.Scan(&n); err != nil {
return nil, fmt.Errorf("scan: %w", err)
}
out = append(out, n)
}
return out, nil
}
Контекст с дедлайном. Дедлайн истёк посреди выборки, rows.Next() вернул false, цикл кончился, функция отдала то, что успела набрать, и nil. Ошибка лежала в rows.Err(), а его никто не вызывал.
Исправление - две строки после цикла, if err := rows.Err(); err != nil и возврат с %w. Всё. Теперь ищу остальные такие циклы.