MCPcopy
hub / github.com/larksuite/cli / HandleResponse

Function HandleResponse

internal/client/response.go:68–165  ·  view source on GitHub ↗

HandleResponse routes a raw *larkcore.ApiResp to the appropriate output: 1. If Content-Type is JSON, check for business errors first (even with --output). 2. If --output is set and response is not a JSON error, save to file. 3. If Content-Type is non-JSON and no --output, auto-save binary to file.

(resp *larkcore.ApiResp, opts ResponseOptions)

Source from the content-addressed store, hash-verified

66// 2. If --output is set and response is not a JSON error, save to file.
67// 3. If Content-Type is non-JSON and no --output, auto-save binary to file.
68func HandleResponse(resp *larkcore.ApiResp, opts ResponseOptions) error {
69 ct := resp.Header.Get("Content-Type")
70 identity := opts.Identity
71 if identity == "" {
72 identity = core.AsUser
73 }
74 check := opts.CheckError
75 if check == nil {
76 // Default check routes through BuildAPIError, producing typed
77 // *errs.PermissionError / AuthenticationError / etc. A zero-value
78 // *APIClient is safe here because BuildAPIError gracefully degrades
79 // identity-aware fields (ConsoleURL etc.) when AppID is empty.
80 check = func(r interface{}, id core.Identity) error {
81 return (&APIClient{}).CheckResponse(r, id)
82 }
83 }
84
85 // Non-JSON error responses (e.g. 404 text/plain from gateway): return error
86 // directly instead of falling through to the binary-save path.
87 if resp.StatusCode >= 400 && !IsJSONContentType(ct) && ct != "" {
88 return httpStatusError(resp.StatusCode, resp.RawBody)
89 }
90
91 // JSON responses: always check for business errors before saving.
92 if IsJSONContentType(ct) || ct == "" {
93 result, err := ParseJSONResponse(resp)
94 if err != nil {
95 // An unparseable / empty body on an HTTP error (common with a
96 // missing Content-Type) must be classified by status, not reported
97 // as an internal decode failure, matching the non-JSON branch above.
98 if resp.StatusCode >= 400 {
99 return httpStatusError(resp.StatusCode, resp.RawBody)
100 }
101 return WrapJSONResponseParseError(err, resp.RawBody)
102 }
103 if apiErr := check(result, identity); apiErr != nil {
104 return apiErr
105 }
106 // CheckResponse treats business code 0 as success, so a 4xx/5xx whose
107 // JSON body omits a non-zero code would otherwise be served as a
108 // successful result. Classify by HTTP status so it is never swallowed.
109 if resp.StatusCode >= 400 {
110 return httpStatusError(resp.StatusCode, resp.RawBody)
111 }
112 if opts.OutputPath != "" {
113 // File downloads keep the existing raw-response scan path because the
114 // saved payload is the API response body, not the success envelope.
115 scanResult := output.ScanForSafety(opts.CommandPath, result, opts.ErrOut)
116 if scanResult.Blocked {
117 return scanResult.BlockErr
118 }
119 if scanResult.Alert != nil {
120 output.WriteAlertWarning(opts.ErrOut, scanResult.Alert)
121 }
122 return saveAndPrint(opts.FileIO, resp, opts.OutputPath, opts.Out)
123 }
124
125 if opts.JqExpr != "" || opts.Format == output.FormatJSON {

Calls 15

ScanForSafetyFunction · 0.92
WriteAlertWarningFunction · 0.92
WriteSuccessEnvelopeFunction · 0.92
SuccessEnvelopeDataFunction · 0.92
FormatValueFunction · 0.92
NewValidationErrorFunction · 0.92
PrintJsonFunction · 0.92
IsJSONContentTypeFunction · 0.85
ParseJSONResponseFunction · 0.85
saveAndPrintFunction · 0.85
SaveResponseFunction · 0.85