feat(doc,markdown,sheets,slides,wiki): emit typed error envelopes across ccm domains#1246
feat(doc,markdown,sheets,slides,wiki): emit typed error envelopes across ccm domains#1246evandance wants to merge 1 commit into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughTyped errs replace legacy output errors across docs, sheets, slides, and wiki shortcuts. Validation is standardized, API calls switch to CallAPITyped, new wrappers normalize network/save errors, and tests assert typed problems. Lint rules expand migrated paths. ChangesTyped errs migration across shortcuts
Estimated code review effort🎯 5 (Critical) | ⏱️ ~110 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
b575abd to
ba0b2dc
Compare
🚀 PR Preview Install Guide🧰 CLI updatenpm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@78e9d4c5970ef0265b04940d2d23998ed97890f6🧩 Skill updatenpx skills add larksuite/cli#feat/errs-migrate-ccm -y -g |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1246 +/- ##
==========================================
+ Coverage 71.58% 71.59% +0.01%
==========================================
Files 689 693 +4
Lines 65521 65561 +40
==========================================
+ Hits 46901 46938 +37
+ Misses 14972 14970 -2
- Partials 3648 3653 +5 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
shortcuts/wiki/wiki_async_task.go (1)
103-119:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTreat a missing async-task result block as an invalid response.
If
/wiki/v2/tasks/{task_id}omitsdelete_space_result/simple_task_result, this parser leavesStatusempty,StatusCode()falls back to"processing", and the poller eventually reports a timeout instead of surfacing the backend contract break. Failing fast here would avoid a misleading “still running” result for malformed task payloads.Suggested fix
func parseWikiAsyncTaskStatus(taskID string, task map[string]interface{}, resultKey string) (wikiAsyncTaskStatus, error) { if task == nil { return wikiAsyncTaskStatus{}, errs.NewInternalError(errs.SubtypeInvalidResponse, "wiki task response missing task") } result := common.GetMap(task, resultKey) + if result == nil { + return wikiAsyncTaskStatus{}, errs.NewInternalError( + errs.SubtypeInvalidResponse, + "wiki task response missing %s", + resultKey, + ) + } status := wikiAsyncTaskStatus{ TaskID: common.GetString(task, "task_id"), } if status.TaskID == "" { status.TaskID = taskID } - if result != nil { - status.Status = common.GetString(result, "status") - status.StatusMsg = common.GetString(result, "status_msg") + status.Status = common.GetString(result, "status") + if strings.TrimSpace(status.Status) == "" { + return wikiAsyncTaskStatus{}, errs.NewInternalError(errs.SubtypeInvalidResponse, "wiki task response missing status") } + status.StatusMsg = common.GetString(result, "status_msg") return status, nil }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@shortcuts/wiki/wiki_async_task.go` around lines 103 - 119, The parser parseWikiAsyncTaskStatus currently treats a missing result block as OK and leaves Status empty; change it to treat a nil result (common.GetMap(task, resultKey) == nil) as an invalid response: when result is nil return an errs.NewInternalError(errs.SubtypeInvalidResponse, "<context> wiki task response missing "+resultKey) instead of continuing, so the caller fails fast on malformed payloads; reference the parseWikiAsyncTaskStatus function and the resultKey parameter to locate and implement this check.shortcuts/wiki/wiki_move.go (1)
624-658:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReject move-task payloads that contain no parseable
move_result.Right now a task payload with no
move_resultentries returns an emptywikiMoveTaskStatus, which the poll loop interprets as “still processing” and eventually times out. That hides an invalid/wiki/v2/tasks/{id}response behind a misleading timeout instead of surfacing it asSubtypeInvalidResponse.Suggested fix
func parseWikiMoveTaskStatus(taskID string, task map[string]interface{}) (wikiMoveTaskStatus, error) { if task == nil { return wikiMoveTaskStatus{}, errs.NewInternalError(errs.SubtypeInvalidResponse, "wiki task response missing task") } status := wikiMoveTaskStatus{ TaskID: common.GetString(task, "task_id"), } if status.TaskID == "" { status.TaskID = taskID } + parsed := 0 for _, item := range common.GetSlice(task, "move_result") { resultMap, ok := item.(map[string]interface{}) if !ok { continue } @@ status.MoveResults = append(status.MoveResults, wikiMoveTaskResult{ Node: node, Status: int(common.GetFloat(resultMap, "status")), StatusMsg: common.GetString(resultMap, "status_msg"), }) + parsed++ + } + + if parsed == 0 { + return wikiMoveTaskStatus{}, errs.NewInternalError(errs.SubtypeInvalidResponse, "wiki move task response missing move_result") } return status, nil }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@shortcuts/wiki/wiki_move.go` around lines 624 - 658, The parseWikiMoveTaskStatus function must treat payloads with no parseable move_result as invalid: after iterating and building status.MoveResults, if len(status.MoveResults) == 0 then return an error (errs.NewInternalError with errs.SubtypeInvalidResponse and a clear message) instead of returning an empty wikiMoveTaskStatus; this change ensures parseWikiMoveTaskStatus (and callers that check wikiMoveTaskStatus) surface invalid /wiki/v2/tasks/{id} responses that lack move_result entries.shortcuts/wiki/wiki_node_get.go (1)
204-230:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReject
--obj-typefor/wiki/<token>URLs too.A
/wiki/...URL resolves to a wikinode_token, but this branch only checks mismatches when the path implies a non-emptyobj_type. That meanswiki +node-get --node-token https://feishu.cn/wiki/wik... --obj-type docxnow passes validation and sends an invalidobj_typetoget_node, instead of failing fast like the raw-node-token path does.Suggested fix
switch { + case spec.ObjType != "" && urlObjType == "": + return wikiNodeGetSpec{}, errs.NewValidationError( + errs.SubtypeInvalidArgument, + "--obj-type is only valid for obj_tokens; %q resolves to a node_token", + spec.Token, + ).WithParam("--obj-type") case spec.ObjType == "" && urlObjType != "": spec.ObjType = urlObjType case spec.ObjType != "" && urlObjType != "" && spec.ObjType != urlObjType: return wikiNodeGetSpec{}, errs.NewValidationError(errs.SubtypeInvalidArgument, "--obj-type %q does not match the obj_type %q implied by the URL path; pass only one",🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@shortcuts/wiki/wiki_node_get.go` around lines 204 - 230, When parsing a tokenInput URL in the wiki node get flow, the code currently only errors when the URL implies a non-empty urlObjType that conflicts with spec.ObjType; you must also reject an explicitly provided --obj-type when the URL path is a plain /wiki/ (i.e., urlObjType == ""), to mirror the raw-node-token behavior. In the URL-handling block (where token, urlObjType, ok := tokenAndObjTypeFromWikiURL(u.Path) is used and spec.SourceKind is set to "url-wiki" or "url-obj"), add a validation: if urlObjType == "" && spec.ObjType != "" return an errs.NewValidationError indicating that --obj-type is not allowed for /wiki/ URLs and attach WithParam("--obj-type"); keep the existing mismatch check for the case urlObjType != "".
🧹 Nitpick comments (1)
.golangci.yml (1)
79-80: ⚡ Quick winUpdate the comment to reflect the expanded scope.
The comment states "errs-no-legacy-helper is drive-only" but line 81 now enforces the rule on five domains: drive, doc, sheets, slides, and wiki.
📝 Suggested comment update
- # errs-no-legacy-helper is drive-only: the shared helpers it bans are - # still used by other domains until their later migration phase. + # errs-no-legacy-helper enforced on fully-migrated shortcut domains + # (drive, doc, sheets, slides, wiki): the shared helpers it bans emit + # legacy output.Err* shapes and are replaced by domain-local typed helpers.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.golangci.yml around lines 79 - 80, Update the inline comment that currently says "errs-no-legacy-helper is drive-only" to reflect that errs-no-legacy-helper now applies to five domains (drive, doc, sheets, slides, and wiki); locate the comment near the errs-no-legacy-helper rule in .golangci.yml and change the wording to indicate the expanded scope (e.g., list the domains or say "applies to drive, doc, sheets, slides, and wiki").
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@shortcuts/wiki/wiki_async_task.go`:
- Around line 103-119: The parser parseWikiAsyncTaskStatus currently treats a
missing result block as OK and leaves Status empty; change it to treat a nil
result (common.GetMap(task, resultKey) == nil) as an invalid response: when
result is nil return an errs.NewInternalError(errs.SubtypeInvalidResponse,
"<context> wiki task response missing "+resultKey) instead of continuing, so the
caller fails fast on malformed payloads; reference the parseWikiAsyncTaskStatus
function and the resultKey parameter to locate and implement this check.
In `@shortcuts/wiki/wiki_move.go`:
- Around line 624-658: The parseWikiMoveTaskStatus function must treat payloads
with no parseable move_result as invalid: after iterating and building
status.MoveResults, if len(status.MoveResults) == 0 then return an error
(errs.NewInternalError with errs.SubtypeInvalidResponse and a clear message)
instead of returning an empty wikiMoveTaskStatus; this change ensures
parseWikiMoveTaskStatus (and callers that check wikiMoveTaskStatus) surface
invalid /wiki/v2/tasks/{id} responses that lack move_result entries.
In `@shortcuts/wiki/wiki_node_get.go`:
- Around line 204-230: When parsing a tokenInput URL in the wiki node get flow,
the code currently only errors when the URL implies a non-empty urlObjType that
conflicts with spec.ObjType; you must also reject an explicitly provided
--obj-type when the URL path is a plain /wiki/ (i.e., urlObjType == ""), to
mirror the raw-node-token behavior. In the URL-handling block (where token,
urlObjType, ok := tokenAndObjTypeFromWikiURL(u.Path) is used and spec.SourceKind
is set to "url-wiki" or "url-obj"), add a validation: if urlObjType == "" &&
spec.ObjType != "" return an errs.NewValidationError indicating that --obj-type
is not allowed for /wiki/ URLs and attach WithParam("--obj-type"); keep the
existing mismatch check for the case urlObjType != "".
---
Nitpick comments:
In @.golangci.yml:
- Around line 79-80: Update the inline comment that currently says
"errs-no-legacy-helper is drive-only" to reflect that errs-no-legacy-helper now
applies to five domains (drive, doc, sheets, slides, and wiki); locate the
comment near the errs-no-legacy-helper rule in .golangci.yml and change the
wording to indicate the expanded scope (e.g., list the domains or say "applies
to drive, doc, sheets, slides, and wiki").
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ab5990db-5311-473f-aef1-f039aa4048ce
📒 Files selected for processing (54)
.golangci.ymllint/errscontract/rule_no_legacy_envelope_literal.goshortcuts/doc/clipboard.goshortcuts/doc/doc_errors.goshortcuts/doc/doc_media_download.goshortcuts/doc/doc_media_insert.goshortcuts/doc/doc_media_preview.goshortcuts/doc/doc_media_upload.goshortcuts/doc/docs_create.goshortcuts/doc/docs_create_v2.goshortcuts/doc/docs_fetch_v2.goshortcuts/doc/docs_search.goshortcuts/doc/docs_update.goshortcuts/doc/docs_update_v2.goshortcuts/doc/helpers.goshortcuts/sheets/helpers.goshortcuts/sheets/lark_sheets_cell_data.goshortcuts/sheets/lark_sheets_cell_images.goshortcuts/sheets/lark_sheets_cell_style_and_merge.goshortcuts/sheets/lark_sheets_dropdown.goshortcuts/sheets/lark_sheets_filter_views.goshortcuts/sheets/lark_sheets_float_images.goshortcuts/sheets/lark_sheets_row_column_management.goshortcuts/sheets/lark_sheets_sheet_manage_test.goshortcuts/sheets/lark_sheets_sheet_management.goshortcuts/sheets/lark_sheets_spreadsheet_management.goshortcuts/sheets/sheets_errors.goshortcuts/slides/helpers.goshortcuts/slides/slides_create.goshortcuts/slides/slides_create_test.goshortcuts/slides/slides_errors.goshortcuts/slides/slides_media_upload.goshortcuts/slides/slides_replace_slide.goshortcuts/slides/slides_replace_slide_test.goshortcuts/wiki/wiki_async_task.goshortcuts/wiki/wiki_async_task_test.goshortcuts/wiki/wiki_delete.goshortcuts/wiki/wiki_delete_test.goshortcuts/wiki/wiki_member_add.goshortcuts/wiki/wiki_member_helpers.goshortcuts/wiki/wiki_member_list.goshortcuts/wiki/wiki_member_remove.goshortcuts/wiki/wiki_member_test.goshortcuts/wiki/wiki_move.goshortcuts/wiki/wiki_move_test.goshortcuts/wiki/wiki_node_copy.goshortcuts/wiki/wiki_node_create.goshortcuts/wiki/wiki_node_create_test.goshortcuts/wiki/wiki_node_delete.goshortcuts/wiki/wiki_node_delete_test.goshortcuts/wiki/wiki_node_get.goshortcuts/wiki/wiki_node_list.goshortcuts/wiki/wiki_space_create.goshortcuts/wiki/wiki_space_list.go
💤 Files with no reviewable changes (1)
- shortcuts/wiki/wiki_member_test.go
ba0b2dc to
029fbd4
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@shortcuts/sheets/lark_sheets_float_images.go`:
- Line 118: The stat error is being mislabeled as "file not found"
unconditionally; update the code that returns sheetsInputStatError(err, "file
not found") to inspect the error (using os.IsNotExist(err)) and only use "file
not found" when IsNotExist is true, otherwise pass a message that includes the
actual error (e.g., err.Error() or fmt.Sprintf("stat error: %v", err)); locate
the call that returns sheetsInputStatError and adjust it to choose the message
based on os.IsNotExist(err) so permission/I/O errors are reported accurately.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bf66eadd-90fa-4244-90a8-57e396adad3c
📒 Files selected for processing (53)
.golangci.ymllint/errscontract/rule_no_legacy_envelope_literal.goshortcuts/doc/clipboard.goshortcuts/doc/doc_errors.goshortcuts/doc/doc_media_download.goshortcuts/doc/doc_media_insert.goshortcuts/doc/doc_media_preview.goshortcuts/doc/doc_media_upload.goshortcuts/doc/docs_create.goshortcuts/doc/docs_create_v2.goshortcuts/doc/docs_fetch_v2.goshortcuts/doc/docs_search.goshortcuts/doc/docs_update.goshortcuts/doc/docs_update_v2.goshortcuts/doc/helpers.goshortcuts/sheets/helpers.goshortcuts/sheets/lark_sheets_cell_data.goshortcuts/sheets/lark_sheets_cell_images.goshortcuts/sheets/lark_sheets_cell_style_and_merge.goshortcuts/sheets/lark_sheets_dropdown.goshortcuts/sheets/lark_sheets_filter_views.goshortcuts/sheets/lark_sheets_float_images.goshortcuts/sheets/lark_sheets_row_column_management.goshortcuts/sheets/lark_sheets_sheet_manage_test.goshortcuts/sheets/lark_sheets_sheet_management.goshortcuts/sheets/lark_sheets_spreadsheet_management.goshortcuts/sheets/sheets_errors.goshortcuts/slides/helpers.goshortcuts/slides/slides_create.goshortcuts/slides/slides_create_test.goshortcuts/slides/slides_errors.goshortcuts/slides/slides_media_upload.goshortcuts/slides/slides_replace_slide.goshortcuts/slides/slides_replace_slide_test.goshortcuts/wiki/wiki_async_task.goshortcuts/wiki/wiki_async_task_test.goshortcuts/wiki/wiki_delete.goshortcuts/wiki/wiki_delete_test.goshortcuts/wiki/wiki_member_add.goshortcuts/wiki/wiki_member_helpers.goshortcuts/wiki/wiki_member_list.goshortcuts/wiki/wiki_member_remove.goshortcuts/wiki/wiki_move.goshortcuts/wiki/wiki_move_test.goshortcuts/wiki/wiki_node_copy.goshortcuts/wiki/wiki_node_create.goshortcuts/wiki/wiki_node_create_test.goshortcuts/wiki/wiki_node_delete.goshortcuts/wiki/wiki_node_delete_test.goshortcuts/wiki/wiki_node_get.goshortcuts/wiki/wiki_node_list.goshortcuts/wiki/wiki_space_create.goshortcuts/wiki/wiki_space_list.go
029fbd4 to
ba49fbc
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
shortcuts/doc/clipboard.go (1)
324-338:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winPreserve Linux tool stderr in the typed failure message.
exec.Command(...).Output()drops stderr here, so xclip/wl-paste/xsel failures collapse toexit status 1. That loses the actionable reason (DISPLAYunset, Wayland/X11 mismatch, missing clipboard owner, etc.) right where the typed envelope is supposed to help the caller recover.💡 Suggested change
for _, t := range tools { if _, lookErr := exec.LookPath(t.name); lookErr != nil { continue } foundTool = true - out, err := exec.Command(t.name, t.args...).Output() + cmd := exec.Command(t.name, t.args...) + var stderr bytes.Buffer + cmd.Stderr = &stderr + out, err := cmd.Output() if err != nil { - lastErr = errs.NewValidationError(errs.SubtypeFailedPrecondition, "clipboard image read failed via %s: %s", t.name, err).WithCause(err) + msg := strings.TrimSpace(stderr.String()) + if msg == "" { + msg = err.Error() + } + lastErr = errs.NewValidationError(errs.SubtypeFailedPrecondition, "clipboard image read failed via %s: %s", t.name, msg).WithCause(err) continue }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@shortcuts/doc/clipboard.go` around lines 324 - 338, The code currently uses exec.Command(t.name, t.args...).Output(), which discards stderr and causes opaque "exit status 1" errors; change to capture stderr (e.g., use CombinedOutput or otherwise capture both stdout and stderr) when running the tool referenced by t.name/t.args, then include the stderr text (or combined output) in the typed failure messages assigned to lastErr (the errs.NewValidationError calls around clipboard image read, empty output, and PNG validation) so the validation error contains the tool name and the stderr/combined output for actionable diagnostics while preserving existing checks like hasPNGMagic and the foundTool flag.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@shortcuts/wiki/wiki_move.go`:
- Around line 593-595: The failure branch currently returns before the async
task_id is made available to the caller; update the status.Failed() handling so
the async task id is preserved and returned to the caller (i.e., keep the
"async" flag true and include the task id in the error/response) instead of
immediately returning status, false, err. Concretely, in the status.Failed()
block in runWikiDocsToWikiMove / wiki_move.go, ensure you let
runWikiDocsToWikiMove write "out" (or extract the task id from the status
object) and return status, true, errs.NewAPIError(... ) that includes the
task_id (or otherwise preserve the task_id field) so follow-up commands can
inspect/retry the non-idempotent move.
---
Outside diff comments:
In `@shortcuts/doc/clipboard.go`:
- Around line 324-338: The code currently uses exec.Command(t.name,
t.args...).Output(), which discards stderr and causes opaque "exit status 1"
errors; change to capture stderr (e.g., use CombinedOutput or otherwise capture
both stdout and stderr) when running the tool referenced by t.name/t.args, then
include the stderr text (or combined output) in the typed failure messages
assigned to lastErr (the errs.NewValidationError calls around clipboard image
read, empty output, and PNG validation) so the validation error contains the
tool name and the stderr/combined output for actionable diagnostics while
preserving existing checks like hasPNGMagic and the foundTool flag.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cbe58f5b-d47d-4c4e-88fa-e1994a10b703
📒 Files selected for processing (53)
.golangci.ymllint/errscontract/rule_no_legacy_envelope_literal.goshortcuts/doc/clipboard.goshortcuts/doc/doc_errors.goshortcuts/doc/doc_media_download.goshortcuts/doc/doc_media_insert.goshortcuts/doc/doc_media_preview.goshortcuts/doc/doc_media_upload.goshortcuts/doc/docs_create.goshortcuts/doc/docs_create_v2.goshortcuts/doc/docs_fetch_v2.goshortcuts/doc/docs_search.goshortcuts/doc/docs_update.goshortcuts/doc/docs_update_v2.goshortcuts/doc/helpers.goshortcuts/sheets/helpers.goshortcuts/sheets/lark_sheets_cell_data.goshortcuts/sheets/lark_sheets_cell_images.goshortcuts/sheets/lark_sheets_cell_style_and_merge.goshortcuts/sheets/lark_sheets_dropdown.goshortcuts/sheets/lark_sheets_filter_views.goshortcuts/sheets/lark_sheets_float_images.goshortcuts/sheets/lark_sheets_row_column_management.goshortcuts/sheets/lark_sheets_sheet_manage_test.goshortcuts/sheets/lark_sheets_sheet_management.goshortcuts/sheets/lark_sheets_spreadsheet_management.goshortcuts/sheets/sheets_errors.goshortcuts/slides/helpers.goshortcuts/slides/slides_create.goshortcuts/slides/slides_create_test.goshortcuts/slides/slides_errors.goshortcuts/slides/slides_media_upload.goshortcuts/slides/slides_replace_slide.goshortcuts/slides/slides_replace_slide_test.goshortcuts/wiki/wiki_async_task.goshortcuts/wiki/wiki_async_task_test.goshortcuts/wiki/wiki_delete.goshortcuts/wiki/wiki_delete_test.goshortcuts/wiki/wiki_member_add.goshortcuts/wiki/wiki_member_helpers.goshortcuts/wiki/wiki_member_list.goshortcuts/wiki/wiki_member_remove.goshortcuts/wiki/wiki_move.goshortcuts/wiki/wiki_move_test.goshortcuts/wiki/wiki_node_copy.goshortcuts/wiki/wiki_node_create.goshortcuts/wiki/wiki_node_create_test.goshortcuts/wiki/wiki_node_delete.goshortcuts/wiki/wiki_node_delete_test.goshortcuts/wiki/wiki_node_get.goshortcuts/wiki/wiki_node_list.goshortcuts/wiki/wiki_space_create.goshortcuts/wiki/wiki_space_list.go
e1fd240 to
7778c6d
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@shortcuts/sheets/backward/lark_sheets_spreadsheet_management.go`:
- Around line 241-244: The output-path safety check currently runs only in
Execute (the runtime.ResolveSavePath call that returns errs.NewValidationError),
causing --dry-run previews to skip this validation; move or duplicate that
validation into the command's Validate phase so the same unsafe path is rejected
during Validate (and thus for dry-run). Concretely, add the
runtime.ResolveSavePath check (and return the same errs.NewValidationError with
WithCause) inside the Validate method or shared input-builder used by Validate,
and remove or keep (idempotently) the Execute check so both phases enforce
identical path validation for the flag handling code that reads outputPath.
In `@shortcuts/sheets/lark_sheet_sheet_structure.go`:
- Around line 162-194: Replace usage of common.ValidationErrorf in
dimInsertInput (and likewise in dimFreezeInput, dimRangeOpInput,
buildDimMovePlan) with the typed-error pattern used elsewhere: return
errs.NewValidationError(errs.SubtypeInvalidArgument,
"<message>").WithParam("<flag>") for missing/invalid flag cases and include
parameter names like "--position", "--count", or the specific flag being
validated; where you currently check runtime.Changed("position") or
runtime.Changed("count") or validate parseA1Position/count, construct and return
the corresponding errs.NewValidationError(...).WithParam("--position") or
WithParam("--count") and preserve the original error message text as the
validation message. Ensure every common.ValidationErrorf(...) call in those
functions is replaced consistently with this errs.NewValidationError pattern.
In `@shortcuts/sheets/lark_sheet_write_cells.go`:
- Around line 211-220: PostMount currently uses
cmd.MarkFlagsOneRequired("start-cell", "range") which only ensures at least one
flag is present but allows both; update enforcement so exactly one is set by
calling Cobra's MarkFlagsMutuallyExclusive("start-cell","range") in PostMount
(in addition to or instead of MarkFlagsOneRequired) and add a defensive check in
csvPutInput that returns an error if both start-cell and range are non-empty
(rejecting the double-set case). Modify references around PostMount,
cmd.MarkFlagsOneRequired, MarkFlagsMutuallyExclusive, and csvPutInput to
implement both the Cobra mutual-exclusion and the explicit runtime validation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d390e31a-04d1-4f46-acbe-39c5f002b0d7
📒 Files selected for processing (67)
.golangci.ymllint/errscontract/rule_no_legacy_envelope_literal.goshortcuts/doc/clipboard.goshortcuts/doc/doc_errors.goshortcuts/doc/doc_media_download.goshortcuts/doc/doc_media_insert.goshortcuts/doc/doc_media_preview.goshortcuts/doc/doc_media_upload.goshortcuts/doc/docs_create.goshortcuts/doc/docs_create_v2.goshortcuts/doc/docs_fetch_v2.goshortcuts/doc/docs_search.goshortcuts/doc/docs_update.goshortcuts/doc/docs_update_v2.goshortcuts/doc/helpers.goshortcuts/sheets/backward/helpers.goshortcuts/sheets/backward/lark_sheets_cell_data.goshortcuts/sheets/backward/lark_sheets_cell_images.goshortcuts/sheets/backward/lark_sheets_cell_style_and_merge.goshortcuts/sheets/backward/lark_sheets_dropdown.goshortcuts/sheets/backward/lark_sheets_filter_views.goshortcuts/sheets/backward/lark_sheets_float_images.goshortcuts/sheets/backward/lark_sheets_row_column_management.goshortcuts/sheets/backward/lark_sheets_sheet_manage_test.goshortcuts/sheets/backward/lark_sheets_sheet_management.goshortcuts/sheets/backward/lark_sheets_spreadsheet_management.goshortcuts/sheets/backward/sheets_errors.goshortcuts/sheets/batch_op_dispatch.goshortcuts/sheets/execute_paths_test.goshortcuts/sheets/flag_schema_validate.goshortcuts/sheets/helpers.goshortcuts/sheets/lark_sheet_batch_update.goshortcuts/sheets/lark_sheet_object_crud.goshortcuts/sheets/lark_sheet_range_operations.goshortcuts/sheets/lark_sheet_range_operations_test.goshortcuts/sheets/lark_sheet_read_data.goshortcuts/sheets/lark_sheet_search_replace.goshortcuts/sheets/lark_sheet_sheet_structure.goshortcuts/sheets/lark_sheet_workbook.goshortcuts/sheets/lark_sheet_write_cells.goshortcuts/sheets/sheet_ai_api.goshortcuts/slides/helpers.goshortcuts/slides/slides_create.goshortcuts/slides/slides_create_test.goshortcuts/slides/slides_errors.goshortcuts/slides/slides_media_upload.goshortcuts/slides/slides_replace_slide.goshortcuts/slides/slides_replace_slide_test.goshortcuts/wiki/wiki_async_task.goshortcuts/wiki/wiki_async_task_test.goshortcuts/wiki/wiki_delete.goshortcuts/wiki/wiki_delete_test.goshortcuts/wiki/wiki_member_add.goshortcuts/wiki/wiki_member_helpers.goshortcuts/wiki/wiki_member_list.goshortcuts/wiki/wiki_member_remove.goshortcuts/wiki/wiki_move.goshortcuts/wiki/wiki_move_test.goshortcuts/wiki/wiki_node_copy.goshortcuts/wiki/wiki_node_create.goshortcuts/wiki/wiki_node_create_test.goshortcuts/wiki/wiki_node_delete.goshortcuts/wiki/wiki_node_delete_test.goshortcuts/wiki/wiki_node_get.goshortcuts/wiki/wiki_node_list.goshortcuts/wiki/wiki_space_create.goshortcuts/wiki/wiki_space_list.go
💤 Files with no reviewable changes (26)
- shortcuts/slides/slides_errors.go
- shortcuts/slides/slides_create_test.go
- shortcuts/slides/slides_replace_slide_test.go
- shortcuts/wiki/wiki_member_helpers.go
- shortcuts/wiki/wiki_member_list.go
- shortcuts/slides/slides_media_upload.go
- shortcuts/wiki/wiki_space_create.go
- shortcuts/wiki/wiki_move_test.go
- shortcuts/wiki/wiki_delete.go
- shortcuts/wiki/wiki_async_task_test.go
- shortcuts/wiki/wiki_async_task.go
- shortcuts/wiki/wiki_node_list.go
- shortcuts/wiki/wiki_node_copy.go
- shortcuts/slides/helpers.go
- shortcuts/wiki/wiki_move.go
- shortcuts/wiki/wiki_space_list.go
- shortcuts/wiki/wiki_node_create_test.go
- shortcuts/wiki/wiki_member_remove.go
- shortcuts/wiki/wiki_member_add.go
- shortcuts/wiki/wiki_node_delete.go
- shortcuts/slides/slides_replace_slide.go
- shortcuts/wiki/wiki_delete_test.go
- shortcuts/slides/slides_create.go
- shortcuts/wiki/wiki_node_delete_test.go
- shortcuts/wiki/wiki_node_create.go
- shortcuts/wiki/wiki_node_get.go
🚧 Files skipped from review as they are similar to previous changes (14)
- shortcuts/doc/doc_errors.go
- shortcuts/doc/docs_create_v2.go
- lint/errscontract/rule_no_legacy_envelope_literal.go
- shortcuts/doc/helpers.go
- shortcuts/doc/docs_update.go
- shortcuts/doc/docs_search.go
- shortcuts/doc/docs_create.go
- shortcuts/doc/docs_update_v2.go
- shortcuts/doc/doc_media_upload.go
- shortcuts/doc/doc_media_preview.go
- shortcuts/doc/doc_media_download.go
- shortcuts/doc/docs_fetch_v2.go
- shortcuts/doc/clipboard.go
- shortcuts/doc/doc_media_insert.go
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@shortcuts/sheets/backward/lark_sheets_spreadsheet_management.go`:
- Around line 241-244: The output-path safety check currently runs only in
Execute (the runtime.ResolveSavePath call that returns errs.NewValidationError),
causing --dry-run previews to skip this validation; move or duplicate that
validation into the command's Validate phase so the same unsafe path is rejected
during Validate (and thus for dry-run). Concretely, add the
runtime.ResolveSavePath check (and return the same errs.NewValidationError with
WithCause) inside the Validate method or shared input-builder used by Validate,
and remove or keep (idempotently) the Execute check so both phases enforce
identical path validation for the flag handling code that reads outputPath.
In `@shortcuts/sheets/lark_sheet_sheet_structure.go`:
- Around line 162-194: Replace usage of common.ValidationErrorf in
dimInsertInput (and likewise in dimFreezeInput, dimRangeOpInput,
buildDimMovePlan) with the typed-error pattern used elsewhere: return
errs.NewValidationError(errs.SubtypeInvalidArgument,
"<message>").WithParam("<flag>") for missing/invalid flag cases and include
parameter names like "--position", "--count", or the specific flag being
validated; where you currently check runtime.Changed("position") or
runtime.Changed("count") or validate parseA1Position/count, construct and return
the corresponding errs.NewValidationError(...).WithParam("--position") or
WithParam("--count") and preserve the original error message text as the
validation message. Ensure every common.ValidationErrorf(...) call in those
functions is replaced consistently with this errs.NewValidationError pattern.
In `@shortcuts/sheets/lark_sheet_write_cells.go`:
- Around line 211-220: PostMount currently uses
cmd.MarkFlagsOneRequired("start-cell", "range") which only ensures at least one
flag is present but allows both; update enforcement so exactly one is set by
calling Cobra's MarkFlagsMutuallyExclusive("start-cell","range") in PostMount
(in addition to or instead of MarkFlagsOneRequired) and add a defensive check in
csvPutInput that returns an error if both start-cell and range are non-empty
(rejecting the double-set case). Modify references around PostMount,
cmd.MarkFlagsOneRequired, MarkFlagsMutuallyExclusive, and csvPutInput to
implement both the Cobra mutual-exclusion and the explicit runtime validation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d390e31a-04d1-4f46-acbe-39c5f002b0d7
📒 Files selected for processing (67)
.golangci.ymllint/errscontract/rule_no_legacy_envelope_literal.goshortcuts/doc/clipboard.goshortcuts/doc/doc_errors.goshortcuts/doc/doc_media_download.goshortcuts/doc/doc_media_insert.goshortcuts/doc/doc_media_preview.goshortcuts/doc/doc_media_upload.goshortcuts/doc/docs_create.goshortcuts/doc/docs_create_v2.goshortcuts/doc/docs_fetch_v2.goshortcuts/doc/docs_search.goshortcuts/doc/docs_update.goshortcuts/doc/docs_update_v2.goshortcuts/doc/helpers.goshortcuts/sheets/backward/helpers.goshortcuts/sheets/backward/lark_sheets_cell_data.goshortcuts/sheets/backward/lark_sheets_cell_images.goshortcuts/sheets/backward/lark_sheets_cell_style_and_merge.goshortcuts/sheets/backward/lark_sheets_dropdown.goshortcuts/sheets/backward/lark_sheets_filter_views.goshortcuts/sheets/backward/lark_sheets_float_images.goshortcuts/sheets/backward/lark_sheets_row_column_management.goshortcuts/sheets/backward/lark_sheets_sheet_manage_test.goshortcuts/sheets/backward/lark_sheets_sheet_management.goshortcuts/sheets/backward/lark_sheets_spreadsheet_management.goshortcuts/sheets/backward/sheets_errors.goshortcuts/sheets/batch_op_dispatch.goshortcuts/sheets/execute_paths_test.goshortcuts/sheets/flag_schema_validate.goshortcuts/sheets/helpers.goshortcuts/sheets/lark_sheet_batch_update.goshortcuts/sheets/lark_sheet_object_crud.goshortcuts/sheets/lark_sheet_range_operations.goshortcuts/sheets/lark_sheet_range_operations_test.goshortcuts/sheets/lark_sheet_read_data.goshortcuts/sheets/lark_sheet_search_replace.goshortcuts/sheets/lark_sheet_sheet_structure.goshortcuts/sheets/lark_sheet_workbook.goshortcuts/sheets/lark_sheet_write_cells.goshortcuts/sheets/sheet_ai_api.goshortcuts/slides/helpers.goshortcuts/slides/slides_create.goshortcuts/slides/slides_create_test.goshortcuts/slides/slides_errors.goshortcuts/slides/slides_media_upload.goshortcuts/slides/slides_replace_slide.goshortcuts/slides/slides_replace_slide_test.goshortcuts/wiki/wiki_async_task.goshortcuts/wiki/wiki_async_task_test.goshortcuts/wiki/wiki_delete.goshortcuts/wiki/wiki_delete_test.goshortcuts/wiki/wiki_member_add.goshortcuts/wiki/wiki_member_helpers.goshortcuts/wiki/wiki_member_list.goshortcuts/wiki/wiki_member_remove.goshortcuts/wiki/wiki_move.goshortcuts/wiki/wiki_move_test.goshortcuts/wiki/wiki_node_copy.goshortcuts/wiki/wiki_node_create.goshortcuts/wiki/wiki_node_create_test.goshortcuts/wiki/wiki_node_delete.goshortcuts/wiki/wiki_node_delete_test.goshortcuts/wiki/wiki_node_get.goshortcuts/wiki/wiki_node_list.goshortcuts/wiki/wiki_space_create.goshortcuts/wiki/wiki_space_list.go
💤 Files with no reviewable changes (26)
- shortcuts/slides/slides_errors.go
- shortcuts/slides/slides_create_test.go
- shortcuts/slides/slides_replace_slide_test.go
- shortcuts/wiki/wiki_member_helpers.go
- shortcuts/wiki/wiki_member_list.go
- shortcuts/slides/slides_media_upload.go
- shortcuts/wiki/wiki_space_create.go
- shortcuts/wiki/wiki_move_test.go
- shortcuts/wiki/wiki_delete.go
- shortcuts/wiki/wiki_async_task_test.go
- shortcuts/wiki/wiki_async_task.go
- shortcuts/wiki/wiki_node_list.go
- shortcuts/wiki/wiki_node_copy.go
- shortcuts/slides/helpers.go
- shortcuts/wiki/wiki_move.go
- shortcuts/wiki/wiki_space_list.go
- shortcuts/wiki/wiki_node_create_test.go
- shortcuts/wiki/wiki_member_remove.go
- shortcuts/wiki/wiki_member_add.go
- shortcuts/wiki/wiki_node_delete.go
- shortcuts/slides/slides_replace_slide.go
- shortcuts/wiki/wiki_delete_test.go
- shortcuts/slides/slides_create.go
- shortcuts/wiki/wiki_node_delete_test.go
- shortcuts/wiki/wiki_node_create.go
- shortcuts/wiki/wiki_node_get.go
🚧 Files skipped from review as they are similar to previous changes (14)
- shortcuts/doc/doc_errors.go
- shortcuts/doc/docs_create_v2.go
- lint/errscontract/rule_no_legacy_envelope_literal.go
- shortcuts/doc/helpers.go
- shortcuts/doc/docs_update.go
- shortcuts/doc/docs_search.go
- shortcuts/doc/docs_create.go
- shortcuts/doc/docs_update_v2.go
- shortcuts/doc/doc_media_upload.go
- shortcuts/doc/doc_media_preview.go
- shortcuts/doc/doc_media_download.go
- shortcuts/doc/docs_fetch_v2.go
- shortcuts/doc/clipboard.go
- shortcuts/doc/doc_media_insert.go
🛑 Comments failed to post (3)
shortcuts/sheets/backward/lark_sheets_spreadsheet_management.go (1)
241-244:
⚠️ Potential issue | 🟡 Minor | ⚡ Quick winValidate
--output-pathbefore the dry-run path too.This safety check only runs in
Execute, so+export --dry-run --output-path ...still produces a successful preview for a path the real command would reject. Moving it intoValidate(or a shared input builder) keeps dry-run/error-contract behavior aligned with the real path.Based on learnings:
Validate-stage rejects in dry-run tests exit non-zero, and this repo already validates user-facing output paths duringValidate.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@shortcuts/sheets/backward/lark_sheets_spreadsheet_management.go` around lines 241 - 244, The output-path safety check currently runs only in Execute (the runtime.ResolveSavePath call that returns errs.NewValidationError), causing --dry-run previews to skip this validation; move or duplicate that validation into the command's Validate phase so the same unsafe path is rejected during Validate (and thus for dry-run). Concretely, add the runtime.ResolveSavePath check (and return the same errs.NewValidationError with WithCause) inside the Validate method or shared input-builder used by Validate, and remove or keep (idempotently) the Execute check so both phases enforce identical path validation for the flag handling code that reads outputPath.shortcuts/sheets/lark_sheet_sheet_structure.go (1)
162-194: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Use
errs.NewValidationErrorconsistently with other migrated sheets shortcuts.This file uses
common.ValidationErrorf(...)for validation errors, but all other sheets shortcuts in this migration (inshortcuts/sheets/backward/) consistently useerrs.NewValidationError(errs.SubtypeInvalidArgument, ...).WithParam("--flag").For consistency with the typed-error migration pattern applied across the rest of
shortcuts/sheets/, these validation helpers should use the same approach.🔄 Example refactor for dimInsertInput
func dimInsertInput(runtime flagView, token, sheetID, sheetName string) (map[string]interface{}, error) { if err := requireSheetSelector(sheetID, sheetName); err != nil { return nil, err } if !runtime.Changed("position") { - return nil, common.ValidationErrorf("--position is required") + return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "--position is required").WithParam("--position") } if !runtime.Changed("count") { - return nil, common.ValidationErrorf("--count is required") + return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "--count is required").WithParam("--count") } position := strings.TrimSpace(runtime.Str("position")) if _, _, err := parseA1Position(position); err != nil { - return nil, common.ValidationErrorf("invalid --position %q: %v", position, err) + return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid --position %q: %v", position, err).WithParam("--position").WithCause(err) } count := runtime.Int("count") if count <= 0 { - return nil, common.ValidationErrorf("--count must be > 0 (got %d)", count) + return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "--count must be > 0 (got %d)", count).WithParam("--count") }Apply the same pattern to
dimFreezeInput,dimRangeOpInput, andbuildDimMovePlan.Also applies to: 324-353, 359-377, 633-651
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@shortcuts/sheets/lark_sheet_sheet_structure.go` around lines 162 - 194, Replace usage of common.ValidationErrorf in dimInsertInput (and likewise in dimFreezeInput, dimRangeOpInput, buildDimMovePlan) with the typed-error pattern used elsewhere: return errs.NewValidationError(errs.SubtypeInvalidArgument, "<message>").WithParam("<flag>") for missing/invalid flag cases and include parameter names like "--position", "--count", or the specific flag being validated; where you currently check runtime.Changed("position") or runtime.Changed("count") or validate parseA1Position/count, construct and return the corresponding errs.NewValidationError(...).WithParam("--position") or WithParam("--count") and preserve the original error message text as the validation message. Ensure every common.ValidationErrorf(...) call in those functions is replaced consistently with this errs.NewValidationError pattern.shortcuts/sheets/lark_sheet_write_cells.go (1)
211-220:
⚠️ Potential issue | 🟠 Major | ⚡ Quick win🧩 Analysis chain
🌐 Web query:
In github.com/spf13/cobra, does MarkFlagsOneRequired enforce mutual exclusivity, or does it only require at least one of the listed flags? Please point to the official Cobra docs or source for Cobra v1.10.x.💡 Result:
MarkFlagsOneRequired in github.com/spf13/cobra does NOT enforce mutual exclusivity. It only requires that at least one of the listed flags is set. In Cobra v1.10.x, MarkFlagsOneRequired is validated by validateOneRequiredFlagGroups, which errors only when none of the flags in the one-required group are set: “at least one of the flags in the group […] is required” [1][2]. Mutual exclusivity is enforced separately by the mutuallyExclusive annotation + validateExclusiveFlagGroups, which errors when more than one flag in the mutually-exclusive group is set [1]. So, MarkFlagsOneRequired alone = “at least one required”; to get “exactly one”, you must also use MarkFlagsMutuallyExclusive for the same flag set (as noted in the PR discussion and example) [3].
Citations:
- 1: https://github.com/spf13/cobra/blob/v1.10.2/flag_groups.go
- 2: https://github.com/spf13/cobra/blob/main/flag_groups.go
- 3: https://github.com/spf13/cobra/pull/1952](https:/togithub.com/spf13/cobra/pull/1952)
Fix
--start-cell/--range“exactly one” enforcement.
cmd.MarkFlagsOneRequired("start-cell", "range")only guarantees that at least one of the flags is set; it does not prevent both--start-celland--rangefrom being provided together. If the contract is “exactly one must be set”, enforce mutual exclusivity via Cobra (e.g.,MarkFlagsMutuallyExclusive) and/or add explicit validation incsvPutInputto reject the double-set case.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@shortcuts/sheets/lark_sheet_write_cells.go` around lines 211 - 220, PostMount currently uses cmd.MarkFlagsOneRequired("start-cell", "range") which only ensures at least one flag is present but allows both; update enforcement so exactly one is set by calling Cobra's MarkFlagsMutuallyExclusive("start-cell","range") in PostMount (in addition to or instead of MarkFlagsOneRequired) and add a defensive check in csvPutInput that returns an error if both start-cell and range are non-empty (rejecting the double-set case). Modify references around PostMount, cmd.MarkFlagsOneRequired, MarkFlagsMutuallyExclusive, and csvPutInput to implement both the Cobra mutual-exclusion and the explicit runtime validation.
5c68a27 to
a8b529a
Compare
d6d99d0 to
9570105
Compare
7c21445 to
44949a5
Compare
44949a5 to
62ccc69
Compare
62ccc69 to
9def5a2
Compare
b0f916a to
564d4df
Compare
…oss ccm domains Classify doc, markdown, sheets, slides, and wiki shortcut failures with typed errors so CLI users and automation receive more specific, actionable diagnostics. Keep the migration scoped to the CCM shortcut domains, their error-contract guards, and the now-unreachable legacy save-error helper cleanup required after those domains stop calling it. Align the common-helper AST guard with latest main's migrated paths without reintroducing shortcuts removed upstream.
564d4df to
78e9d4c
Compare
Summary
Migrates typed error envelopes across the CCM shortcut domains: doc, markdown, sheets, slides, and wiki. Scope is limited to those domains, error-contract guards, and cleanup of a legacy common helper made unreachable by the migration.
Changes
errs.*envelopes..golangci.ymlandlint/errscontractcoverage for doc, markdown, sheets, slides, and wiki.common.WrapSaveErrorByCategoryhelper.Test Plan
78e9d4c5.Related Issues