@@ -15,6 +15,7 @@ import (
1515 "strings"
1616 "unicode/utf8"
1717
18+ "github.com/larksuite/cli/errs"
1819 "github.com/larksuite/cli/internal/core"
1920 "github.com/larksuite/cli/internal/output"
2021 "github.com/larksuite/cli/shortcuts/common"
@@ -216,19 +217,17 @@ func executeSearchUserSingle(ctx context.Context, runtime *common.RuntimeContext
216217 if err != nil {
217218 return err
218219 }
219- if apiResp .StatusCode != http .StatusOK {
220- return output .ErrAPI (apiResp .StatusCode , http .StatusText (apiResp .StatusCode ), string (apiResp .RawBody ))
221- }
222220
223- var resp searchUserAPIEnvelope
224- if err := json . Unmarshal ( apiResp . RawBody , & resp ); err != nil {
225- return output . ErrWithHint ( output . ExitInternal , "validation" , "unmarshal response failed" , err . Error ())
221+ data , err := runtime . ClassifyAPIResponse ( apiResp )
222+ if err != nil {
223+ return err
226224 }
227- if resp .Code != 0 {
228- return output .ErrAPI (resp .Code , resp .Msg , string (apiResp .RawBody ))
225+ respData , err := decodeSearchUserAPIData (data )
226+ if err != nil {
227+ return err
229228 }
230229
231- users , hasMore := projectUsers (resp . Data , runtime .Str ("lang" ), runtime .Config .Brand )
230+ users , hasMore := projectUsers (respData , runtime .Str ("lang" ), runtime .Config .Brand )
232231 out := searchUserResponse {Users : users , HasMore : hasMore }
233232
234233 runtime .OutFormat (out , & output.Meta {Count : len (users )}, func (w io.Writer ) {
@@ -245,6 +244,20 @@ func executeSearchUserSingle(ctx context.Context, runtime *common.RuntimeContext
245244 return nil
246245}
247246
247+ func decodeSearchUserAPIData (data map [string ]interface {}) (* searchUserAPIData , error ) {
248+ raw , err := json .Marshal (data )
249+ if err != nil {
250+ return nil , errs .NewInternalError (errs .SubtypeInvalidResponse , "marshal search user response data failed" ).
251+ WithCause (err )
252+ }
253+ var out searchUserAPIData
254+ if err := json .Unmarshal (raw , & out ); err != nil {
255+ return nil , errs .NewInternalError (errs .SubtypeInvalidResponse , "decode search user response data failed" ).
256+ WithCause (err )
257+ }
258+ return & out , nil
259+ }
260+
248261func isHumanReadableFormat (format string ) bool {
249262 return format == "pretty" || format == "table"
250263}
@@ -373,52 +386,74 @@ func rowFromItem(item *searchUserAPIItem, lang string, brand core.LarkBrand) sea
373386
374387func validateSearchUser (runtime * common.RuntimeContext ) error {
375388 if ! hasAnySearchInput (runtime ) {
376- return common .FlagErrorf (
389+ return common .ValidationErrorf (
377390 "specify at least one of --query, --queries, --user-ids, --has-chatted, --has-enterprise-email, --exclude-external-users, --left-organization" ,
391+ ).WithParams (
392+ errs.InvalidParam {Name : "--query" , Reason : "required; specify at least one search input" },
393+ errs.InvalidParam {Name : "--queries" , Reason : "required; specify at least one search input" },
394+ errs.InvalidParam {Name : "--user-ids" , Reason : "required; specify at least one search input" },
395+ errs.InvalidParam {Name : "--has-chatted" , Reason : "required; specify at least one search input" },
396+ errs.InvalidParam {Name : "--has-enterprise-email" , Reason : "required; specify at least one search input" },
397+ errs.InvalidParam {Name : "--exclude-external-users" , Reason : "required; specify at least one search input" },
398+ errs.InvalidParam {Name : "--left-organization" , Reason : "required; specify at least one search input" },
378399 )
379400 }
380401
381402 queriesRaw := strings .TrimSpace (runtime .Str ("queries" ))
382403 if queriesRaw != "" {
383404 if strings .TrimSpace (runtime .Str ("query" )) != "" {
384- return common .FlagErrorf ("--query and --queries are mutually exclusive" )
405+ return common .ValidationErrorf ("--query and --queries are mutually exclusive" ).
406+ WithParams (
407+ errs.InvalidParam {Name : "--query" , Reason : "mutually exclusive with --queries" },
408+ errs.InvalidParam {Name : "--queries" , Reason : "mutually exclusive with --query" },
409+ )
385410 }
386411 if strings .TrimSpace (runtime .Str ("user-ids" )) != "" {
387- return common .FlagErrorf ("--user-ids and --queries are mutually exclusive" )
412+ return common .ValidationErrorf ("--user-ids and --queries are mutually exclusive" ).
413+ WithParams (
414+ errs.InvalidParam {Name : "--user-ids" , Reason : "mutually exclusive with --queries" },
415+ errs.InvalidParam {Name : "--queries" , Reason : "mutually exclusive with --user-ids" },
416+ )
388417 }
389418 queries := parseAndDedupQueries (queriesRaw )
390419 if len (queries ) == 0 {
391- return common .FlagErrorf ("--queries: no valid query parsed from %q (separate entries with ',')" , queriesRaw )
420+ return common .ValidationErrorf ("--queries: no valid query parsed from %q (separate entries with ',')" , queriesRaw ).
421+ WithParam ("--queries" )
392422 }
393423 if len (queries ) > maxFanoutQueries {
394- return common .FlagErrorf ("--queries: must be at most %d entries (got %d)" , maxFanoutQueries , len (queries ))
424+ return common .ValidationErrorf ("--queries: must be at most %d entries (got %d)" , maxFanoutQueries , len (queries )).
425+ WithParam ("--queries" )
395426 }
396427 for _ , q := range queries {
397428 if utf8 .RuneCountInString (q ) > maxSearchUserQueryChars {
398- return common .FlagErrorf ("--queries: entry %q exceeds %d characters" , q , maxSearchUserQueryChars )
429+ return common .ValidationErrorf ("--queries: entry %q exceeds %d characters" , q , maxSearchUserQueryChars ).
430+ WithParam ("--queries" )
399431 }
400432 }
401433 }
402434
403435 if q := strings .TrimSpace (runtime .Str ("query" )); q != "" {
404436 if utf8 .RuneCountInString (q ) > maxSearchUserQueryChars {
405- return common .FlagErrorf ("--query: length must be between 1 and %d characters" , maxSearchUserQueryChars )
437+ return common .ValidationErrorf ("--query: length must be between 1 and %d characters" , maxSearchUserQueryChars ).
438+ WithParam ("--query" )
406439 }
407440 }
408441
409442 if raw := strings .TrimSpace (runtime .Str ("user-ids" )); raw != "" {
410- ids , err := common .ResolveOpenIDs ("--user-ids" , common .SplitCSV (raw ), runtime )
443+ ids , err := common .ResolveOpenIDsTyped ("--user-ids" , common .SplitCSV (raw ), runtime )
411444 if err != nil {
412445 return err
413446 }
414447 if len (ids ) == 0 {
415- return common .FlagErrorf ("--user-ids: no valid open_id parsed from %q (separate entries with ',')" , raw )
448+ return common .ValidationErrorf ("--user-ids: no valid open_id parsed from %q (separate entries with ',')" , raw ).
449+ WithParam ("--user-ids" )
416450 }
417451 if len (ids ) > maxSearchUserUserIDs {
418- return common .FlagErrorf ("--user-ids: must be at most %d entries" , maxSearchUserUserIDs )
452+ return common .ValidationErrorf ("--user-ids: must be at most %d entries" , maxSearchUserUserIDs ).
453+ WithParam ("--user-ids" )
419454 }
420455 for _ , id := range ids {
421- if _ , err := common .ValidateUserID ( id ); err != nil {
456+ if _ , err := common .ValidateUserIDTyped ( "--user-ids" , id ); err != nil {
422457 return err
423458 }
424459 }
@@ -429,15 +464,16 @@ func validateSearchUser(runtime *common.RuntimeContext) error {
429464 // silent wrong-result bugs.
430465 for _ , bf := range searchUserBoolFilters {
431466 if runtime .Cmd .Flags ().Changed (bf .Flag ) && ! runtime .Bool (bf .Flag ) {
432- return common .FlagErrorf (
467+ return common .ValidationErrorf (
433468 "--%s: pass the flag to enable the filter; omit it to disable filtering (=false is rejected to prevent silent wrong results)" ,
434469 bf .Flag ,
435- )
470+ ). WithParam ( "--" + bf . Flag )
436471 }
437472 }
438473
439474 if n := runtime .Int ("page-size" ); n < 1 || n > maxSearchUserPageSize {
440- return common .FlagErrorf ("--page-size: must be between 1 and %d" , maxSearchUserPageSize )
475+ return common .ValidationErrorf ("--page-size: must be between 1 and %d" , maxSearchUserPageSize ).
476+ WithParam ("--page-size" )
441477 }
442478 return nil
443479}
@@ -473,7 +509,7 @@ func buildSearchUserBody(runtime *common.RuntimeContext) (*searchUserAPIRequest,
473509 hasFilter := false
474510
475511 if raw := strings .TrimSpace (runtime .Str ("user-ids" )); raw != "" {
476- ids , err := common .ResolveOpenIDs ("--user-ids" , common .SplitCSV (raw ), runtime )
512+ ids , err := common .ResolveOpenIDsTyped ("--user-ids" , common .SplitCSV (raw ), runtime )
477513 if err != nil {
478514 return nil , err
479515 }
0 commit comments