<commit_before>package main

import (
	"fmt"
	"net"
	"time"
)

const protoFmt = "ntwrk%s :%s\r\n"
const timeout = time.Duration(15) * time.Second

// testContext holds a test function, action name, and address to connect to.
type testContext struct {
	Action string
	Fn     func(net.Conn, time.Duration) (int64, error)
	Addr   string
}

// startClient starts the network test suite.
func startClient(host string, port int) {
	addr := fmt.Sprintf("%s:%d", host, port)
	perform(testContext{"download", download, addr})
	perform(testContext{"upload", upload, addr})
}

// perform runs a network test and prints the recorded bandwidth.
func perform(ctx testContext) {
	conn := openConn(ctx.Addr, ctx.Action)

	since := time.Now()
	ticker := time.NewTicker(time.Millisecond * 150)
	go func() {
		for t := range ticker.C {
			elapsed := t.Sub(since)
			progress := formatProgress(elapsed, timeout)
			fmt.Printf("\r %9s: %s", ctx.Action, progress)
		}
	}()
	defer ticker.Stop()

	bytes, err := ctx.Fn(conn, timeout)
	if err != nil {
		fmt.Printf("error: %s\n", err.Error())
		return
	}

	elapsed := time.Since(since).Seconds()
	fmt.Printf(" %s\n", formatBytes(bytes, elapsed))
}

// openConn opens a connection to `host` and writes a formatted message to it.
func openConn(host string, action string) (conn net.Conn) {
	conn, err := net.Dial("tcp", host)
	if err != nil {
		panic(err)
	}

	fmt.Fprintf(conn, protoFmt, proto, action)
	return
}

// whoami requests the client's external IP address from `host` and prints it.
func whoami(host string, port int) {
	addr := fmt.Sprintf("%s:%d", host, port)
	resp := make([]byte, 40)
	conn := openConn(addr, "whoami")
	conn.Read(resp)
	fmt.Print(string(resp))
}<commit_msg>Add error handling to `openConn`<commit_after>package main

import (
	"fmt"
	"net"
	"time"
)

const protoFmt = "ntwrk%s :%s\r\n"
const timeout = time.Duration(15) * time.Second

// testContext holds a test function, action name, and address to connect to.
type testContext struct {
	Action string
	Fn     func(net.Conn, time.Duration) (int64, error)
	Addr   string
}

// startClient starts the network test suite.
func startClient(host string, port int) {
	addr := fmt.Sprintf("%s:%d", host, port)
	perform(testContext{"download", download, addr})
	perform(testContext{"upload", upload, addr})
}

// perform runs a network test and prints the recorded bandwidth.
func perform(ctx testContext) {
	conn, err := openConn(ctx.Addr, ctx.Action)
	if err != nil {
		fmt.Printf("error: %s\n", err.Error())
		return
	}

	since := time.Now()
	ticker := time.NewTicker(time.Millisecond * 150)
	go func() {
		for t := range ticker.C {
			elapsed := t.Sub(since)
			progress := formatProgress(elapsed, timeout)
			fmt.Printf("\r %9s: %s", ctx.Action, progress)
		}
	}()
	defer ticker.Stop()

	bytes, err := ctx.Fn(conn, timeout)
	if err != nil {
		fmt.Printf("error: %s\n", err.Error())
		return
	}

	elapsed := time.Since(since).Seconds()
	fmt.Printf(" %s\n", formatBytes(bytes, elapsed))
}

// openConn opens a connection to `host` and writes a formatted message to it.
func openConn(host string, action string) (conn net.Conn, err error) {
	conn, err = net.Dial("tcp", host)
	if err != nil {
		return
	}

	fmt.Fprintf(conn, protoFmt, proto, action)
	return
}

// whoami requests the client's external IP address from `host` and prints it.
func whoami(host string, port int) {
	addr := fmt.Sprintf("%s:%d", host, port)
	resp := make([]byte, 40)

	conn, err := openConn(addr, "whoami")
	if err != nil {
		fmt.Printf("error: %s\n", err.Error())
		return
	}

	conn.Read(resp)
	fmt.Print(string(resp))
}
{'fraction_non_alphanumeric': 0.15337593776048902, 'fraction_numerical': 0.005557099194220617, 'mean_word_length': 4.034965034965035, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4381869', 'n_tokens_mistral': 1304, 'n_tokens_neox': 1252, 'n_words': 376}