{"record":{"id":"d4a1941afa29bb70","repo":"unknwon/the-way-to-go_ZH_CN","slug":"error","errorCode":null,"errorMessage":"Error: ","messagePattern":"Error: ","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"eBook/exercises/chapter_15/client1.go","lineNumber":44,"sourceCode":"\ttrimmedClient := strings.Trim(clientName, \"\\r\\n\") // \"\\r\\n\" voor Windows, \"\\n\" voor Linux\n\n\tfor {\n\t\tfmt.Println(\"What to send to the server? Type Q to quit. Type SH to shutdown server.\")\n\t\tinput, _ = inputReader.ReadString('\\n')\n\t\ttrimmedInput := strings.Trim(input, \"\\r\\n\")\n\t\t// fmt.Printf(\"input:--%s--\",input)\n\t\t// fmt.Printf(\"trimmedInput:--%s--\",trimmedInput)\n\t\tif trimmedInput == \"Q\" {\n\t\t\treturn\n\t\t}\n\t\t_, error = conn.Write([]byte(trimmedClient + \" says: \" + trimmedInput))\n\t\tcheckError(error)\n\t}\n}\n\nfunc checkError(error error) {\n\tif error != nil {\n\t\tpanic(\"Error: \" + error.Error()) // terminate program\n\t}\n}\n","sourceCodeStart":26,"sourceCodeEnd":47,"githubUrl":"https://github.com/unknwon/the-way-to-go_ZH_CN/blob/7a54d34d3657084b6a59e5618bd069b912d571aa/eBook/exercises/chapter_15/client1.go#L26-L47","documentation":"Panic raised by checkError in the chapter-15 TCP chat client (client1.go). Every network operation in the exercise funnels through checkError, which converts any non-nil error from conn.Write into a program-terminating panic with message 'Error: <err>'. The design is intentional for brevity: one failed send kills the whole client process.","triggerScenarios":"conn.Write([]byte(trimmedClient + \" says: \" + trimmedInput)) returns a non-nil error: the companion server1.go exited, the TCP connection was reset by the peer, or the network path dropped between connect and send (errors like 'broken pipe' or 'connection reset by peer').","commonSituations":"Starting client1.go before server1.go (or after the server itself panicked via its own checkError); typing 'Q'-follow-up messages after the server closed the socket; firewall/NAT dropping an idle connection; dialing the wrong host/port so the failure surfaces at net.Dial just before this loop.","solutions":["Start the companion server (server1.go) first and confirm it is listening on the exact host:port the client dials, then restart the client","Replace checkError(error) after conn.Write with inline handling: on error, print it, close the connection, and return (or reconnect) instead of panicking","If the abort style must stay, wrap the client loop in a deferred recover that prints the panic value and exits with a friendly message","Read the error suffix: 'broken pipe'/'connection reset' means the peer went away — restart the server rather than hunting for a client bug"],"exampleFix":"// before\n_, error = conn.Write([]byte(trimmedClient + \" says: \" + trimmedInput))\ncheckError(error)\n\n// after\nif _, err := conn.Write([]byte(trimmedClient + \" says: \" + trimmedInput)); err != nil {\n    fmt.Fprintln(os.Stderr, \"send failed:\", err)\n    return\n}","handlingStrategy":"try-catch","validationCode":"func serverUp(addr string) bool {\n    c, err := net.DialTimeout(\"tcp\", addr, 2*time.Second)\n    if err != nil {\n        return false\n    }\n    c.Close()\n    return true\n}\n\n// before entering the chat loop:\nif !serverUp(serverAddr) {\n    log.Fatal(\"chat server is not reachable at\", serverAddr)\n}","typeGuard":null,"tryCatchPattern":"// Go's catch: deferred recover around the write loop\ndefer func() {\n    if r := recover(); r != nil {\n        fmt.Fprintln(os.Stderr, \"client aborted:\", r)\n        os.Exit(1)\n    }\n}()\nfor {\n    _, err := conn.Write(msg)\n    if err != nil { // prefer this: never let write errors reach panic\n        break\n    }\n}","preventionTips":["Start the companion server before the client and share one addr constant between them","Treat write/read errors as loop-exit conditions, not panic triggers","Probe the server with net.DialTimeout before investing in an interactive session"],"tags":["go","network","tcp","client","panic","chat"],"backgroundTag":null,"analyzedSha":"7a54d34d3657084b6a59e5618bd069b912d571aa","analyzedAt":"2026-08-15T15:13:06.026Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}