Skip to content

Commit

Permalink
Fix.
Browse files Browse the repository at this point in the history
  • Loading branch information
russjones committed Nov 28, 2024
1 parent 6cae726 commit 473d37b
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 25 deletions.
23 changes: 13 additions & 10 deletions lib/srv/app/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (t *transport) RoundTrip(r *http.Request) (*http.Response, error) {
resp, err := t.tr.RoundTrip(r)
if message, ok := utils.CanExplainNetworkError(err); ok {
t.log.DebugContext(r.Context(), "Request failed with a network error.",
"raw_error", err, "human_error", message)
"raw_error", err, "human_error", strings.Join(strings.Fields(message), " "))

code := trace.ErrorToCode(err)
return &http.Response{
Expand Down Expand Up @@ -324,17 +324,20 @@ func host(addr string) string {

// charWrap wraps a line to about 80 characters to make it easier to read.
func charWrap(message string) string {
var n int
var sb strings.Builder
for _, word := range strings.Fields(message) {
sb.WriteString(word)
sb.WriteString(" ")

n += len(word) + 1
if n > 80 {
sb.WriteString("\n")
n = 0
for _, line := range strings.Split(message, "\n") {
var n int
for _, word := range strings.Fields(line) {
sb.WriteString(word)
sb.WriteString(" ")

n += len(word) + 1
if n > 80 {
sb.WriteString("\n")
n = 0
}
}
sb.WriteString("\n")
}
return sb.String()
}
Expand Down
42 changes: 27 additions & 15 deletions lib/utils/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,42 +99,54 @@ func CanExplainNetworkError(err error) (string, bool) {
//
// dial tcp 127.0.0.1:8000: connect: connection refused
case errors.Is(err, syscall.ECONNREFUSED):
return "Connection refused. Run \"nc -vz a.b.c.d PORT\" on the Teleport " +
"agent to verify the target application is running and listening on " +
"the expected host and port.", true
return `Connection Refused
Teleport was unable to connect to the requested host, possibly because the server is not running. Ensure the server is running and listening on the correct port.
Use "nc -vz HOST PORT" to help debug this issue.`, true
// Host unreachable errors can be reproduced by running
// "ip route add unreachable a.b.c.d" to update the routing table to make
// "ip route add unreachable HOST" to update the routing table to make
// the host unreachable. Packets will be discarded and an ICMP message
// will be returned. The raw error typically looks like the following:
//
// dial tcp 10.10.10.10:8000: connect: no route to host
case errors.Is(err, syscall.EHOSTUNREACH):
return "No route to host. Run \"ip route get a.b.c.d\" on the Teleport " +
"agent to verify a route to the target application exists in the " +
"routing table.", true
return `No Route to Host
Teleport could not connect to the requested host, likely because there is no valid network path to reach it. Check the network routing table to ensure a valid path to the host exists.
Use "ping HOST" and "ip route get HOST" to help debug this issue.`, true
// Connection reset errors can be reproduced by creating a HTTP server that
// accepts requests but closes the connection before writing a response. The
// raw error typically looks like the following:
//
// read tcp 127.0.0.1:49764->127.0.0.1:8000: read: connection reset by peer
case errors.Is(err, syscall.ECONNRESET):
return "Connection reset by peer. Run \"curl -v a.b.c.d\" on the Teleport " +
"agent to verify the target application (or a load balancer in the " +
"network path) is not abruptly closing the connection after accepting it.", true
return `Connection Reset by Peer
Teleport could not complete the request because the server abruptly closed the connection before the response was received. To resolve this issue, ensure the server (or load balancer) does not have a timeout terminating the connection early and verify that the server is not crash looping.
Use protocol-specific tools (e.g., curl, psql) to help debug this issue.`, true
// Slow responses can be reprodued by creating a HTTP server that does a
// time.Sleep before responding. The raw error typically looks like the following:
//
// context deadline exceeded
case errors.Is(err, context.DeadlineExceeded):
return "Timeout waiting for response. Run \"curl -v a.b.c.d\" on the " +
"Teleport agent to verify the target application is not under excessive load.", true
return `Context Deadline Exceeded
Teleport did not receive a response within timeout, likely due to the system being overloaded or due to network congestion. To resolve this issue, connect to the host directly and ensure it is responding promptly.
Use protocol-specific tools (e.g., curl, psql) to assist in debugging this issue.`, true
// No such host errors can be reproduced by attempting to resolve a invalid
// domain name. The raw error typically looks like the following:
//
// dial tcp: lookup fasfasfasf.com: no such host
// dial tcp: lookup qweqweqwe.com: no such host
case errors.As(err, &derr) && derr.IsNotFound:
return "No such host. Run \"dig +short fqdn\" on the Teleport agent to " +
"verify the target application has a valid DNS entry.", true
return `No Such Host
Teleport was unable to resolve the provided domain name, likely because the domain does not exist. To resolve this issue, verify the domain is correct and ensure the DNS resolver is properly resolving it.
Use "dig +short HOST" to help debug this issue.`, true
}

return "", false
Expand Down

0 comments on commit 473d37b

Please sign in to comment.