mirror of
https://github.com/larksuite/cli.git
synced 2026-07-07 00:55:53 +08:00
Drive-domain errors now leave the CLI as typed, machine-branchable envelopes — a stable `type` plus `subtype` and named fields (param, params, retryable, log_id, hint) — so scripts and AI agents can branch on structure and act on a recovery hint instead of parsing prose. Changes: - Every error produced in the drive domain — validation, file I/O, and the failures returned from its Lark API calls — is emitted as a typed errs.* error; the exit code is derived from the error category. Drive's API calls now go through a shared typed classifier, so failures carry subtype, troubleshooter, a recovery hint, and the request's log_id whether the server returns it in the response body or the x-tt-logid header; an already-typed network/auth error is never downgraded into a generic API error. - Known API conditions (resource conflict, cross-tenant, cross-brand, ...) carry a recovery hint keyed by their error class; a command can refine that hint with command-specific guidance. - Batch partial failures (+push / +pull / +sync, where some items succeed and some fail) now report an honest ok:false multi-status result on stdout — the summary and every per-item outcome stay machine-readable — and exit non-zero, instead of a misleading ok:true success envelope. - Duplicate rel_path conflicts report each colliding path as a structured params entry (RFC 7807 invalid-params style). - Static guards lock the drive path so legacy error construction — direct envelopes or the auto-classifying API helpers — cannot be reintroduced, making drive the template for the remaining domains. Output changes worth noting for consumers: - Error envelopes now carry typed type/subtype and named fields; exit codes follow the error category (malformed or incomplete API responses are reported as internal errors rather than generic API errors). - Batch partial failures (+push / +pull / +sync) emit an ok:false result envelope on stdout (summary + per-item items[]) and exit non-zero; the per-item results stay on stdout rather than in a stderr error envelope. Errors surfaced through shared cross-domain helpers (scope precheck, media import upload, metadata lookup, save-path resolution) are not yet typed; they migrate with the shared layer in a follow-up change.
44 lines
1.5 KiB
Go
44 lines
1.5 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package errclass
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/larksuite/cli/errs"
|
|
)
|
|
|
|
// TestLookupCodeMeta_DriveCodes pins each drive-service code registered via the
|
|
// codemeta_drive.go init() merge to its expected Category/Subtype/Retryable.
|
|
// Each case traces to repo evidence (see codemeta_drive.go comments).
|
|
func TestLookupCodeMeta_DriveCodes(t *testing.T) {
|
|
cases := []struct {
|
|
code int
|
|
wantCat errs.Category
|
|
wantSubtype errs.Subtype
|
|
wantRetry bool
|
|
}{
|
|
// 1061044: upload with a nonexistent parent folder token. The drive E2E
|
|
// (tests_e2e/drive/2026_06_01_errs_migrate_drive_test.go) drives this
|
|
// producer via a nonexistent parent folder → referenced resource missing.
|
|
{1061044, errs.CategoryAPI, errs.SubtypeNotFound, false},
|
|
// 1069302: comment endpoint's opaque "Invalid or missing parameters"
|
|
// (shortcuts/drive/drive_add_comment.go) → API-side parameter rejection.
|
|
{1069302, errs.CategoryAPI, errs.SubtypeInvalidParameters, false},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(fmt.Sprintf("%d", tc.code), func(t *testing.T) {
|
|
meta, ok := LookupCodeMeta(tc.code)
|
|
if !ok {
|
|
t.Fatalf("code %d not registered in codeMeta", tc.code)
|
|
}
|
|
if meta.Category != tc.wantCat || meta.Subtype != tc.wantSubtype || meta.Retryable != tc.wantRetry {
|
|
t.Errorf("code %d: got %+v, want Category=%v Subtype=%v Retryable=%v",
|
|
tc.code, meta, tc.wantCat, tc.wantSubtype, tc.wantRetry)
|
|
}
|
|
})
|
|
}
|
|
}
|