Documentation
¶
Index ¶
- Constants
- Variables
- func ClassifyLarkError(code int, msg string) (int, string, string)deprecated
- func ExitCodeForCategory(cat errs.Category) int
- func ExitCodeOf(err error) int
- func ExtractItems(data interface{}) []interface{}
- func FindArrayField(data map[string]interface{}) string
- func FormatAsCSV(w io.Writer, data interface{})
- func FormatAsCSVPaginated(w io.Writer, data interface{}, isFirstPage bool)
- func FormatAsTable(w io.Writer, data interface{})
- func FormatAsTablePaginated(w io.Writer, data interface{}, isFirstPage bool)
- func FormatValue(w io.Writer, data interface{}, format Format)
- func GetNotice() map[string]interface{}
- func JqFilter(w io.Writer, data interface{}, expr string) error
- func JqFilterRaw(w io.Writer, data interface{}, expr string) error
- func MarkRaw(err error) error
- func PrintError(w io.Writer, msg string)
- func PrintJson(w io.Writer, data interface{})
- func PrintNdjson(w io.Writer, data interface{})
- func PrintSuccess(w io.Writer, msg string)
- func PrintTable(w io.Writer, rows []map[string]interface{})
- func ValidateJqExpression(expr string) error
- func ValidateJqFlags(jqExpr, outputFlag, format string) error
- func WriteAlertWarning(w io.Writer, alert *extcs.Alert)
- func WriteErrorEnvelope(w io.Writer, err *ExitError, identity string)deprecated
- func WriteTypedErrorEnvelope(w io.Writer, err error, identity string) bool
- type Envelope
- type ErrDetaildeprecated
- type ErrorEnvelopedeprecated
- type ExitErrordeprecated
- func ErrAPI(larkCode int, msg string, detail any) *ExitErrordeprecated
- func ErrAuth(format string, args ...any) *ExitError
- func ErrBare(code int) *ExitErrordeprecated
- func ErrNetwork(format string, args ...any) *ExitError
- func ErrValidation(format string, args ...any) *ExitError
- func ErrWithHint(code int, errType, msg, hint string) *ExitErrordeprecated
- func Errorf(code int, errType, format string, args ...any) *ExitErrordeprecated
- type Format
- type Meta
- type PaginatedFormatter
- type RiskDetaildeprecated
- type ScanResult
Constants ¶
const ( Dim = "\033[2m" Bold = "\033[1m" Yellow = "\033[33m" Cyan = "\033[36m" Red = "\033[31m" Green = "\033[32m" Reset = "\033[0m" )
const ( ExitOK = 0 // 成功 ExitAPI = 1 // API / 通用错误(含 permission、not_found、conflict、rate_limit) ExitValidation = 2 // 参数校验失败 ExitAuth = 3 // 认证失败(token 无效 / 过期),或登录成功但请求 scopes 未全部授予 ExitNetwork = 4 // 网络错误(连接超时、DNS 解析失败等) ExitInternal = 5 // 内部错误(不应发生) ExitContentSafety = 6 // content safety violation (block mode) ExitConfirmationRequired = 10 // 高风险操作需要 --yes 确认(agent 协议信号) )
Fine-grained error types (permission, not_found, rate_limit, etc.) are communicated via the JSON error envelope's "type" field, not via exit codes.
const ( // Auth: token missing / invalid / expired. LarkErrTokenMissing = 99991661 // Authorization header missing or empty LarkErrTokenBadFmt = 99991671 // token format error (must start with "t-" or "u-") LarkErrTokenInvalid = 99991668 // user_access_token invalid or expired LarkErrATInvalid = 99991663 // access_token invalid (generic) LarkErrTokenExpired = 99991677 // user_access_token expired, refresh to obtain a new one // Permission: scope not granted. LarkErrAppScopeNotEnabled = 99991672 // app has not applied for the required API scope LarkErrTokenNoPermission = 99991676 // token lacks the required scope LarkErrUserScopeInsufficient = 99991679 // user has not granted the required scope LarkErrUserNotAuthorized = 230027 // user not authorized // App credential / status. LarkErrAppCredInvalid = 99991543 // app_id or app_secret is incorrect LarkErrAppNotInUse = 99991662 // app is disabled or not installed in this tenant // Rate limit. LarkErrRateLimit = 99991400 // request frequency limit exceeded // Refresh token errors (authn service). LarkErrRefreshInvalid = 20026 // refresh_token invalid or v1 format LarkErrRefreshExpired = 20037 // refresh_token expired LarkErrRefreshRevoked = 20064 // refresh_token revoked LarkErrRefreshAlreadyUsed = 20073 // refresh_token already consumed (single-use rotation) // Drive shortcut / cross-space constraints. LarkErrDriveResourceContention = 1061045 // resource contention occurred, please retry LarkErrDriveCrossTenantUnit = 1064510 // cross tenant and unit not support LarkErrDriveCrossBrand = 1064511 // cross brand not support // Wiki write-path lock contention (e.g. concurrent wiki +node-create under the // same parent). Server-side write lock; transient, safe to retry with backoff. LarkErrWikiLockContention = 131009 // Sheets float image: width/height/offset out of range or invalid. LarkErrSheetsFloatImageInvalidDims = 1310246 // Drive permission apply: per-user-per-document submission limit (5/day) reached. LarkErrDrivePermApplyRateLimit = 1063006 // Drive permission apply: request is not applicable for this document // (e.g. the document is configured to disallow access requests, or the // caller already holds the requested permission, or the target type does // not accept apply operations). LarkErrDrivePermApplyNotApplicable = 1063007 // IM resource ownership mismatch. LarkErrOwnershipMismatch = 231205 // Mail send: account / mailbox-level failures returned by // POST /open-apis/mail/v1/user_mailboxes/:user_mailbox_id/drafts/:draft_id/send. // Mail v1 uses service-scoped 123xxxx codes; keep the full upstream code // because ErrAPI preserves Detail.Code exactly as returned by the server. // These codes indicate the entire batch will keep failing identically and // are consumed by shortcuts/mail.isFatalSendErr to abort early. LarkErrMailboxNotFound = 1234013 // mailbox not found or not active LarkErrMailSendQuotaUser = 1236007 // user daily send count exceeded LarkErrMailSendQuotaUserExt = 1236008 // user daily external recipient count exceeded LarkErrMailSendQuotaTenantExt = 1236009 // tenant daily external recipient count exceeded LarkErrMailQuota = 1236010 // mail quota limit LarkErrTenantStorageLimit = 1236013 // tenant storage limit exceeded )
Lark API generic error code constants. ref: https://open.feishu.cn/document/server-docs/api-call-guide/generic-error-code
Kept as exported identifiers because external shortcut packages reference them by name (e.g. LarkErrOwnershipMismatch). The canonical Category / Subtype / Retryable metadata for each code lives in internal/errclass and must remain the single source of truth — ClassifyLarkError below resolves classification through errclass.LookupCodeMeta.
Variables ¶
var PendingNotice func() map[string]interface{}
PendingNotice, if set, returns system-level notices to inject as the "_notice" field in JSON output envelopes. Set by cmd/root.go. Returns nil when there is nothing to report.
Functions ¶
func ClassifyLarkError
deprecated
ClassifyLarkError maps a Lark API error code + message to the legacy (exitCode, errType, hint) tuple consumed by the *ExitError path.
Classification (Category / Subtype) is sourced from errclass.LookupCodeMeta — the single source of truth shipped for both this legacy adapter and the stage-2+ typed pipeline (errclass.BuildAPIError, not yet invoked in production). This function adapts that result back to the legacy tuple shape for callers that still go through *ExitError:
- exitCode: derived from (Category, Subtype) via legacyExitCode below. Note this differs from the typed pipeline's ExitCodeForCategory in two preserved-legacy-quirks: Authorization+permission subtypes return ExitAPI (legacy treats "permission" as exit 1) and Config returns ExitAuth (legacy bundles "check app_id/secret" under exit 3).
- errType: legacy short string per (Category, Subtype), mapped by legacyErrType. Subtypes not present in the legacy taxonomy fall back to "api_error".
- hint: per-code lookup in legacyHints; "" when absent.
Unknown codes (LookupCodeMeta returns false) classify as (ExitAPI, "api_error", "") — matching the prior default.
Deprecated: ClassifyLarkError belongs to the legacy *output.ExitError surface that predates the typed error contract introduced by errs/. New code MUST NOT use it — classify Lark API responses via internal/errclass.BuildAPIError, which emits a typed *errs.XxxError with Category, Subtype, and identity-aware extension fields populated at the source. This helper is retained only while existing call sites are migrated; it will be removed once they have moved to the typed surface.
func ExitCodeForCategory ¶ added in v1.0.41
ExitCodeForCategory maps an errs.Category to the shell exit code. Multiple categories may share an exit code (Authentication / Authorization / Config all map to 3), so the relationship is many-to-one.
func ExitCodeOf ¶ added in v1.0.41
ExitCodeOf returns the shell exit code for any error.
- typed errors (*errs.PermissionError, *errs.APIError, ...) → routed by Category
- legacy *output.ExitError → uses its own Code field
- *core.ConfigError → reaches the dispatcher as a legacy *output.ExitError via cmd/root asExitError (stage 1); the typed promotion path through internal/errcompat.PromoteConfigError is reserved for stage 2+.
- untyped → ExitInternal
func ExtractItems ¶
func ExtractItems(data interface{}) []interface{}
ExtractItems extracts the data array from a response. It tries two strategies in order:
- Lark API envelope: result["data"][arrayField] (e.g. {"code":0,"data":{"items":[…]}})
- Direct map: result[arrayField] (e.g. {"members":[…],"total":5})
If data is already a plain []interface{}, it is returned as-is.
func FindArrayField ¶
FindArrayField finds the primary array field in a response's data object. It first checks knownArrayFields in priority order, then falls back to the lexicographically smallest unknown array field for deterministic results.
func FormatAsCSV ¶
FormatAsCSV formats data as CSV (with header) and writes it to w.
func FormatAsCSVPaginated ¶
FormatAsCSVPaginated formats data as CSV with pagination awareness. When isFirstPage is true, outputs the header row; otherwise only data rows.
func FormatAsTable ¶
FormatAsTable formats data as a table and writes it to w.
- []interface{} (array of objects) → header + separator + rows
- map[string]interface{} (single object) → key-value two-column table
- empty array → "(empty)"
func FormatAsTablePaginated ¶
FormatAsTablePaginated formats data as a table with pagination awareness. When isFirstPage is true, outputs the header; otherwise only data rows.
func FormatValue ¶
FormatValue formats a single response and writes it to w.
func GetNotice ¶ added in v1.0.1
func GetNotice() map[string]interface{}
GetNotice returns the current pending notice for struct-based callers. Returns nil when there is nothing to report.
func JqFilter ¶ added in v1.0.3
JqFilter applies a jq expression to data and writes the results to w. Scalar values are printed raw (no quotes for strings), matching jq -r behavior. Complex values (maps, arrays) are printed as indented JSON with Go's default HTML escaping (<, >, & → <, >, &).
func JqFilterRaw ¶ added in v1.0.19
JqFilterRaw is like JqFilter but disables HTML escaping when re-marshaling complex jq results. Use it alongside OutRaw when the upstream envelope carries XML/HTML content that must survive --jq '.data.document' style projections without getting mangled into < escapes.
func MarkRaw ¶
MarkRaw sets Raw=true on an ExitError so that the dispatcher skips enrichment (e.g. enrichPermissionError, enrichMissingScopeError) and preserves the original API error detail. Returns the original error unchanged if it is not (or does not wrap) an ExitError.
Used by `cmd/api` and other "passthrough" call sites where the caller explicitly wants the raw Lark API detail (log_id, troubleshooter, etc.) on the wire rather than the enriched message/hint variant.
func PrintNdjson ¶
PrintNdjson prints data as NDJSON (Newline Delimited JSON) to w.
func PrintSuccess ¶
PrintSuccess prints a success message to w.
func PrintTable ¶
PrintTable prints rows as a table to w. Delegates to FormatAsTable for flattening, column union, and width handling.
func ValidateJqExpression ¶ added in v1.0.3
ValidateJqExpression checks whether a jq expression is syntactically valid.
func ValidateJqFlags ¶ added in v1.0.3
ValidateJqFlags checks --jq flag compatibility with --output and --format flags, and validates the jq expression syntax. Returns nil if jqExpr is empty.
func WriteAlertWarning ¶ added in v1.0.18
WriteAlertWarning writes a human-readable content-safety warning to w. Used by non-JSON output paths (pretty, table, csv) in warn mode.
func WriteErrorEnvelope
deprecated
WriteErrorEnvelope writes a JSON error envelope for the given ExitError to w.
Deprecated: WriteErrorEnvelope is the legacy envelope writer paired with *output.ExitError, which predates the typed error contract introduced by errs/. New code MUST NOT call this directly — return a typed *errs.XxxError from the command, and cmd/root.go handleRootError will dispatch through WriteTypedErrorEnvelope. This writer is retained only while existing *ExitError producers are migrated; it will be removed once they have moved to the typed surface.
func WriteTypedErrorEnvelope ¶ added in v1.0.41
WriteTypedErrorEnvelope writes the JSON error envelope for a typed error. Each typed error owns its wire shape via its own struct tags: Problem fields are promoted to the top level through embedding, and extension fields (MissingScopes, ChallengeURL, etc.) sit alongside as siblings — not inside a `detail` sub-object.
Returns true when err was a typed error (envelope written) and false when err had no Problem (caller should fall back to WriteErrorEnvelope).
Types ¶
type Envelope ¶
type Envelope struct {
OK bool `json:"ok"`
Identity string `json:"identity,omitempty"`
Data interface{} `json:"data,omitempty"`
Meta *Meta `json:"meta,omitempty"`
ContentSafetyAlert interface{} `json:"_content_safety_alert,omitempty"`
Notice map[string]interface{} `json:"_notice,omitempty"`
}
Envelope is the standard success response wrapper.
type ErrDetail
deprecated
type ErrDetail struct {
Type string `json:"type"`
Code int `json:"code,omitempty"`
Message string `json:"message"`
Hint string `json:"hint,omitempty"`
ConsoleURL string `json:"console_url,omitempty"`
Risk *RiskDetail `json:"risk,omitempty"`
Detail interface{} `json:"detail,omitempty"`
}
ErrDetail describes a structured error.
Deprecated: ErrDetail belongs to the legacy *output.ExitError surface that predates the typed error contract introduced by errs/. New code MUST NOT use it — typed errs.* structs embed errs.Problem and own their wire shape via JSON tags (Category, Subtype, Hint, etc. promote to the top level). This struct is retained only while existing *ExitError call sites are migrated; it will be removed once they have moved to the typed surface.
type ErrorEnvelope
deprecated
type ErrorEnvelope struct {
OK bool `json:"ok"`
Identity string `json:"identity,omitempty"`
Error *ErrDetail `json:"error"`
Meta *Meta `json:"meta,omitempty"`
Notice map[string]interface{} `json:"_notice,omitempty"`
}
ErrorEnvelope is the standard error response wrapper.
Deprecated: ErrorEnvelope belongs to the legacy *output.ExitError surface that predates the typed error contract introduced by errs/. New code MUST NOT use it — the typed envelope shape is owned by internal/output.WriteTypedErrorEnvelope which marshals typed errs.* errors directly via JSON reflection (no wrapper struct needed). This struct is retained only while existing *ExitError call sites are migrated; it will be removed once they have moved to the typed surface.
type ExitError
deprecated
type ExitError struct {
Code int
Detail *ErrDetail
Err error
Raw bool // when true, the dispatcher skips enrichment (e.g. enrichPermissionError) and preserves the original error detail
}
ExitError is a structured error that carries an exit code and optional detail. It is propagated up the call chain and handled by main.go to produce a JSON error envelope on stderr and the correct exit code.
Deprecated: *output.ExitError is the legacy error type that predates the typed error contract introduced by errs/. New code MUST NOT instantiate it — return a typed *errs.XxxError (see errs/ for the available categories: *AuthenticationError / *PermissionError / *ValidationError / *NetworkError / *APIError / *InternalError / etc.). This type is retained only while existing call sites are migrated; it will be removed once they have moved to the typed surface.
func ErrAPI
deprecated
ErrAPI creates an API ExitError using ClassifyLarkError. For permission errors, uses a concise message; the raw API response is preserved in Detail.
Deprecated: ErrAPI belongs to the legacy *output.ExitError surface that predates the typed error contract introduced by errs/. New code SHOULD construct a typed *errs.XxxError directly. The stage-2+ migration will route classification through internal/errclass.BuildAPIError (shipped but not yet invoked from production paths) so the typed envelope carries Category, Subtype, MissingScopes, ConsoleURL, and Identity from the source. This helper is retained only while existing call sites are migrated; it will be removed once they have moved to the typed surface.
func ErrAuth ¶
ErrAuth creates an authentication ExitError (exit 3, wire type "auth").
Stage-1 status: kept as the canonical helper for token-missing / login-required errors, so the 19 existing call sites in cmd/auth, cmd/config, cmd/event, internal/client, and shortcuts/common keep emitting `type: "auth"`. To migrate a single call site to the typed taxonomy (`type: "authentication"` on the wire), construct `&errs.AuthenticationError{...}` directly — but note that flips a user-visible wire field and belongs in the per-domain stage-2 PR for that area, not in unrelated new code.
func ErrBare
deprecated
ErrBare creates an ExitError with only an exit code and no envelope. Used for cases like `auth check` where the JSON output is already written to stdout.
Deprecated: ErrBare belongs to the legacy *output.ExitError surface that predates the typed error contract introduced by errs/. New code MUST NOT use it — express the "exit with code, emit no envelope" semantics explicitly at the call site (e.g. return a typed *errs.XxxError or call os.Exit directly from RunE). This helper is retained only while existing call sites are migrated; it will be removed once they have moved to the typed surface.
func ErrNetwork ¶
ErrNetwork creates a network ExitError (exit 4, wire type "network"). The legacy *output.ExitError envelope emits only `type`+`message` — no `subtype`/`cause` extension fields.
Stage-1 status: still acceptable to use in new code that only needs the (type, message) pair. To carry extension fields (Subtype "transport" / "timeout" / "tls" / "dns", retryable hint, etc.) on the wire, construct `&errs.NetworkError{...}` directly. Per-domain typed migration in stage 2+ will migrate existing call sites and remove this helper.
func ErrValidation ¶
ErrValidation creates a validation ExitError (exit 2, wire type "validation"). The legacy *output.ExitError envelope emits only `type`+`message` — no `subtype`/`param` extension fields.
Stage-1 status: still acceptable to use in new code that only needs the (type, message) pair. To carry extension fields (Subtype, Param, etc.) on the wire, construct `&errs.ValidationError{...}` directly so cmd/root.go routes it through the typed envelope writer. Per-domain typed migration in stage 2+ will migrate existing call sites and remove this helper.
func ErrWithHint
deprecated
ErrWithHint creates an ExitError with a hint string.
Deprecated: ErrWithHint belongs to the legacy *output.ExitError surface that predates the typed error contract introduced by errs/. New code MUST NOT use it — construct a typed *errs.XxxError directly and set its Hint field (the typed envelope promotes Problem.Hint to the wire). This helper is retained only while existing call sites are migrated; it will be removed once they have moved to the typed surface.
func Errorf
deprecated
Errorf creates an ExitError with the given code, type, and formatted message.
Deprecated: Errorf belongs to the legacy *output.ExitError surface that predates the typed error contract introduced by errs/. New code MUST NOT use it — construct a typed *errs.XxxError directly (e.g. *errs.ValidationError, *errs.InternalError). This helper is retained only while existing call sites are migrated; it will be removed once they have moved to the typed surface.
type Format ¶
type Format int
Format represents an output format type.
func ParseFormat ¶
ParseFormat parses a format string into a Format value. The second return value is false if the format string was not recognized, in which case FormatJSON is returned as default.
type PaginatedFormatter ¶
type PaginatedFormatter struct {
W io.Writer
Format Format
// contains filtered or unexported fields
}
PaginatedFormatter holds state across paginated calls to ensure consistent columns (table/csv use the first page's columns for all pages).
func NewPaginatedFormatter ¶
func NewPaginatedFormatter(w io.Writer, format Format) *PaginatedFormatter
NewPaginatedFormatter creates a formatter that tracks pagination state.
func (*PaginatedFormatter) FormatPage ¶
func (pf *PaginatedFormatter) FormatPage(data interface{})
FormatPage formats one page of items.
type RiskDetail
deprecated
added in
v1.0.21
RiskDetail carries agent-protocol risk information alongside confirmation_required errors. Level is one of "read" | "write" | "high-risk-write". Action identifies the command for the agent (e.g. "mail +send", "drive.files.delete").
Deprecated: RiskDetail is reachable only via *output.ExitError.Detail.Risk, part of the legacy envelope surface that predates the typed error contract introduced by errs/. New code MUST NOT use it — confirmation-required signals belong on *errs.ConfirmationRequiredError (its own typed extension fields can carry agent-protocol metadata directly). This struct is retained only while existing *ExitError call sites are migrated; it will be removed once they have moved to the typed surface.
type ScanResult ¶ added in v1.0.18
ScanResult holds the output of ScanForSafety.
func ScanForSafety ¶ added in v1.0.18
func ScanForSafety(cmdPath string, data any, errOut io.Writer) ScanResult
ScanForSafety runs content-safety scanning on the given data. cmdPath is the raw cobra CommandPath(). When MODE=off, no provider registered, or the command is not allowlisted, returns a zero ScanResult.