classifyNetworkSubtype maps an error chain to one of the network subtypes, falling back to SubtypeNetworkTransport. Timeout is checked first because a net.OpError can satisfy net.Error and also wrap a DNS sub-error in pathological proxy configurations — we prefer the timeout signal.
(err error)
| 72 | // a net.OpError can satisfy net.Error and also wrap a DNS sub-error in |
| 73 | // pathological proxy configurations — we prefer the timeout signal. |
| 74 | func classifyNetworkSubtype(err error) errs.Subtype { |
| 75 | // (a) Timeout — net.Error.Timeout(), plus the SDK's typed timeout |
| 76 | // errors (which do not implement net.Error). |
| 77 | var netErr net.Error |
| 78 | if errors.As(err, &netErr) && netErr.Timeout() { |
| 79 | return errs.SubtypeNetworkTimeout |
| 80 | } |
| 81 | var sdkServerTimeout *larkcore.ServerTimeoutError |
| 82 | if errors.As(err, &sdkServerTimeout) { |
| 83 | return errs.SubtypeNetworkTimeout |
| 84 | } |
| 85 | var sdkClientTimeout *larkcore.ClientTimeoutError |
| 86 | if errors.As(err, &sdkClientTimeout) { |
| 87 | return errs.SubtypeNetworkTimeout |
| 88 | } |
| 89 | |
| 90 | // (b) TLS — typed x509 error or message substring fallback. |
| 91 | var x509Err *x509.UnknownAuthorityError |
| 92 | if errors.As(err, &x509Err) { |
| 93 | return errs.SubtypeNetworkTLS |
| 94 | } |
| 95 | msg := err.Error() |
| 96 | if strings.Contains(msg, "x509:") || strings.Contains(msg, "tls:") { |
| 97 | return errs.SubtypeNetworkTLS |
| 98 | } |
| 99 | |
| 100 | // (c) DNS — *net.DNSError covers SDK chains coming from net.Dialer. |
| 101 | var dnsErr *net.DNSError |
| 102 | if errors.As(err, &dnsErr) { |
| 103 | return errs.SubtypeNetworkDNS |
| 104 | } |
| 105 | |
| 106 | // HTTP 5xx classification lives on the call sites with *http.Response |
| 107 | // access (DoStream, HandleResponse); the SDK never surfaces non-504 5xx |
| 108 | // as an error here. |
| 109 | return errs.SubtypeNetworkTransport |
| 110 | } |
| 111 | |
| 112 | // isJSONDecodeError reports whether err is a JSON decode failure at the |
| 113 | // SDK boundary, matching both typed json errors and their fmt.Errorf- |