WrapDoAPIError converts SDK-boundary failures into typed errs.* errors: already-typed errors pass through (idempotent), JSON-decode failures become InternalError{SubtypeInvalidResponse}, everything else becomes NetworkError with a chain-derived subtype (timeout / tls / dns / server_error / transport
(err error)
| 27 | // NetworkError with a chain-derived subtype (timeout / tls / dns / |
| 28 | // server_error / transport-fallback). |
| 29 | func WrapDoAPIError(err error) error { |
| 30 | if err == nil { |
| 31 | return nil |
| 32 | } |
| 33 | |
| 34 | // (1) Pass-through any typed errs.* error. |
| 35 | if _, ok := errs.ProblemOf(err); ok { |
| 36 | return err |
| 37 | } |
| 38 | |
| 39 | // (2) JSON-decode failure at the SDK boundary → InternalError. |
| 40 | if isJSONDecodeError(err) { |
| 41 | return errs.NewInternalError(errs.SubtypeInvalidResponse, |
| 42 | "SDK returned an invalid JSON response: %v", err). |
| 43 | WithHint("%s", rawAPIJSONHint). |
| 44 | WithCause(err) |
| 45 | } |
| 46 | |
| 47 | // (3) Otherwise classify as a network failure with a chain-derived subtype. |
| 48 | return errs.NewNetworkError(classifyNetworkSubtype(err), |
| 49 | "API call failed: %v", err). |
| 50 | WithCause(err) |
| 51 | } |
| 52 | |
| 53 | // WrapJSONResponseParseError lifts a response-layer JSON parse failure into |
| 54 | // *errs.InternalError{Subtype: SubtypeInvalidResponse}. Empty body, malformed |