Skip to content

fix: migrate task shortcut errors from bare fmt.Errorf to structured …#740

Merged
zero-my merged 1 commit into
larksuite:mainfrom
Zhang-986:fix/task-structured-errors
May 6, 2026
Merged

fix: migrate task shortcut errors from bare fmt.Errorf to structured …#740
zero-my merged 1 commit into
larksuite:mainfrom
Zhang-986:fix/task-structured-errors

Conversation

@Zhang-986

@Zhang-986 Zhang-986 commented May 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Migrated 16 error paths in the task management shortcuts (shortcuts/task/) from bare fmt.Errorf to structured output.Errorf/output.ErrValidation, enabling AI agent consumers (Claude Code, Cursor, Gemini CLI) to programmatically parse and recover from errors via the JSON error envelope contract.

Per AGENTS.md: "RunE functions must return output.Errorf / output.ErrWithHint — never bare fmt.Errorf. AI agents parse stderr as JSON; bare errors break this contract."

Changes

Error migration (16 paths across 4 files)

task_util.go (2 paths — validation errors):

  • parseRelativeTime: invalid format → output.ErrValidation
  • parseRelativeTime: unknown unit → output.ErrValidation

shortcuts.go (4 paths — 3 validation + 1 API):

  • buildTaskCreateBody: invalid --data JSON → output.ErrValidation
  • buildTaskCreateBody: invalid --due time → output.ErrValidation
  • buildTaskCreateBody: missing summary → output.ErrValidation
  • CreateTask.Execute: response parse failure → output.Errorf(ExitAPI, "api_error", ...)

task_update.go (4 paths — 3 validation + 1 API):

  • UpdateTask.Execute: response parse failure → output.Errorf(ExitAPI, "api_error", ...)
  • buildTaskUpdateBody: invalid --data JSON → output.ErrValidation
  • buildTaskUpdateBody: invalid --due time → output.ErrValidation
  • buildTaskUpdateBody: no fields to update → output.ErrValidation

task_query_helpers.go (6 paths — all validation):

  • parseTimeRangeMillis: invalid start/end timestamp → output.ErrValidation
  • parseTimeRangeMillis: reversed time range → output.ErrValidation
  • parseTimeRangeRFC3339: invalid start/end timestamp → output.ErrValidation
  • parseTimeRangeRFC3339: reversed time range → output.ErrValidation

Test additions

  • task_util_test.go: Added TestParseRelativeTime_StructuredErrors — verifies *output.ExitError type, exit code, and error detail type.
  • task_body_test.go (new): Added TestBuildTaskCreateBody_StructuredErrors and TestBuildTaskUpdateBody_StructuredErrors — validates structured error output for invalid JSON data, missing summary, and no-fields-to-update cases.
  • task_query_helpers_test.go: Enhanced existing tests with *output.ExitError type assertions for reversed time range errors.

Test plan

  • go test ./shortcuts/task/... -race — all pass
  • go vet ./shortcuts/task/... — clean
  • gofmt -l shortcuts/task/ — no output
  • go mod tidy — no changes
  • golangci-lint run --new-from-rev=origin/main ./shortcuts/task/... — 0 issues
  • Dry-run E2E: not required (internal refactor, no shortcut flag/param changes)
  • Live E2E: not required (error behavior is structurally identical, just wrapped in ExitError)

Summary by CodeRabbit

  • Bug Fixes

    • Standardized error handling so input validation issues (invalid JSON, missing/blank summaries, invalid due dates/times, reversed time ranges, empty updates, invalid relative-time formats) return consistent validation errors; API response parse failures now return structured API errors.
  • Tests

    • Added unit tests verifying structured error types and metadata for validation, time-range, relative-time parsing, and API parsing failure scenarios.

Copilot AI review requested due to automatic review settings May 1, 2026 11:01
@CLAassistant

CLAassistant commented May 1, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions Bot added domain/task PR touches the task domain size/M Single-domain feat or fix with limited business impact labels May 1, 2026
@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Standardizes error handling in the task shortcuts: input/parse failures now return structured validation exit errors (output.ErrValidation(...)) and API JSON parse failures use output.Errorf(output.ExitAPI, "api_error", ...). Tests added/updated to assert these structured error responses.

Changes

Task shortcuts — validation & API error standardization

Layer / File(s) Summary
Imports / small shape
shortcuts/task/... shortcuts/task/shortcuts.go, shortcuts/task/task_query_helpers.go, shortcuts/task/task_update.go, shortcuts/task/task_util.go
Add internal/output import across task shortcut files to enable structured exit errors.
Validation error conversions
shortcuts/task/shortcuts.go, shortcuts/task/task_update.go, shortcuts/task/task_query_helpers.go, shortcuts/task/task_util.go
Replace plain fmt.Errorf(...) return paths for invalid JSON, due parsing, missing/blank summary, invalid time ranges, and relative-time parsing with output.ErrValidation(...) calls and adjusted messages.
API error conversion
shortcuts/task/shortcuts.go, shortcuts/task/task_update.go
Replace response parsing errors with output.Errorf(output.ExitAPI, "api_error", ...) to produce structured API exit errors.
Tests: assert structured errors
shortcuts/task/task_body_test.go, shortcuts/task/task_query_helpers_test.go, shortcuts/task/task_util_test.go
Add and update tests to assert returned errors are *output.ExitError, verify Code == output.ExitValidation and Detail.Type == "validation" where applicable, and check error detail substrings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • LuckyTerry
  • liangshuo-1
  • tengchengwei

"I nibble bugs and tidy trails of code,
Turn vague errors into a structured ode,
Validation whispers, API faults disclosed,
Tests stand guard where messy inputs goad,
A carrot-coded cheer for clearer mode!" 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: migrating error handling from bare fmt.Errorf to structured output.Errorf/ErrValidation across task shortcuts.
Description check ✅ Passed The PR description comprehensively covers all required sections: detailed summary with context from AGENTS.md, organized list of 16 error migrations across 4 files, new test additions with descriptions, and complete test plan with verification steps.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates error returns in the task shortcuts (shortcuts/task/) from bare fmt.Errorf to structured internal/output errors (output.Errorf / output.ErrValidation) to preserve the CLI’s JSON error envelope contract for AI agent consumers.

Changes:

  • Replaced validation errors with output.ErrValidation in task body/time parsing helpers.
  • Replaced API response unmarshal errors with output.Errorf(output.ExitAPI, "api_error", ...).
  • Added/updated tests to assert returned errors are *output.ExitError with the expected exit codes and detail types.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
shortcuts/task/task_util.go Converts parseRelativeTime failures to structured validation errors.
shortcuts/task/shortcuts.go Converts create-body validation errors + create response parse errors to structured output errors.
shortcuts/task/task_update.go Converts update-body validation errors + update response parse errors to structured output errors.
shortcuts/task/task_query_helpers.go Converts time-range parsing validation failures to structured validation errors.
shortcuts/task/task_util_test.go Adds structured-error assertions for parseRelativeTime.
shortcuts/task/task_body_test.go Adds new structured-error tests for create/update body builders.
shortcuts/task/task_query_helpers_test.go Adds structured-error assertions for reversed time-range cases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread shortcuts/task/task_query_helpers_test.go
Comment thread shortcuts/task/task_util_test.go
Comment thread shortcuts/task/task_body_test.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
shortcuts/task/task_query_helpers_test.go (1)

257-286: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Mirror the structured validation assertion here.

The RFC3339 case only checks the exit code. Please also assert Detail.Type == "validation" like the millis case so this path is covered by the same contract.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/task/task_query_helpers_test.go` around lines 257 - 286, In the
parseTimeRangeRFC3339 test, extend the validation for the "reversed range fails
fast" case to mirror the millis-case assertions: after asserting the error is an
*output.ExitError and that exitErr.Code == output.ExitValidation (within the
t.Run for parseTimeRangeRFC3339), also assert exitErr.Detail.Type ==
"validation" so the RFC3339 path enforces the same contract; reference
parseTimeRangeRFC3339, output.ExitError, output.ExitValidation, and
exitErr.Detail.Type when adding this assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shortcuts/task/task_body_test.go`:
- Around line 16-76: Add assertions in TestBuildTaskCreateBody_StructuredErrors
to verify the error message contains the expected substring (tt.wantSubstr).
After you obtain exitErr from buildTaskCreateBody, assert that
exitErr.Detail.Message (or exitErr.Error() if Message is empty) contains
tt.wantSubstr using strings.Contains; reference the test name
TestBuildTaskCreateBody_StructuredErrors, the table field wantSubstr, and the
error variable exitErr to locate where to add the check so the structured-error
tests fail on message regressions.

In `@shortcuts/task/task_util_test.go`:
- Around line 23-62: The test TestParseRelativeTime_StructuredErrors defines
wantSubstr but never asserts the human-readable message; update the test to
assert that exitErr.Detail.Message (the error text on the structured detail)
contains tt.wantSubstr using strings.Contains and t.Errorf when it does not, so
the validation message is checked for the expected substring after the existing
non-nil and Type assertions around parseRelativeTime.

---

Outside diff comments:
In `@shortcuts/task/task_query_helpers_test.go`:
- Around line 257-286: In the parseTimeRangeRFC3339 test, extend the validation
for the "reversed range fails fast" case to mirror the millis-case assertions:
after asserting the error is an *output.ExitError and that exitErr.Code ==
output.ExitValidation (within the t.Run for parseTimeRangeRFC3339), also assert
exitErr.Detail.Type == "validation" so the RFC3339 path enforces the same
contract; reference parseTimeRangeRFC3339, output.ExitError,
output.ExitValidation, and exitErr.Detail.Type when adding this assertion.
🪄 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: 2819e420-0d47-4916-ba99-fe6033c41dbd

📥 Commits

Reviewing files that changed from the base of the PR and between 7fb71c6 and d534423.

📒 Files selected for processing (7)
  • shortcuts/task/shortcuts.go
  • shortcuts/task/task_body_test.go
  • shortcuts/task/task_query_helpers.go
  • shortcuts/task/task_query_helpers_test.go
  • shortcuts/task/task_update.go
  • shortcuts/task/task_util.go
  • shortcuts/task/task_util_test.go

Comment thread shortcuts/task/task_body_test.go
Comment thread shortcuts/task/task_util_test.go
@Zhang-986
Zhang-986 force-pushed the fix/task-structured-errors branch from 07765cd to 0f3be77 Compare May 1, 2026 11:35

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shortcuts/task/task_update.go`:
- Around line 134-137: After unmarshalling dataStr into taskObj using
json.Unmarshal in the block that checks runtime.Str("data"), add a nil-check for
taskObj and either initialize it to an empty map (e.g., taskObj =
make(map[string]interface{})) or return a validation error if the caller passed
JSON null; this prevents panics when later code assigns taskObj["summary"],
taskObj["description"], and taskObj["due"]. Locate the json.Unmarshal call and
runtime.Str("data") check and ensure taskObj is non-nil before any field
assignments, preserving the existing output.ErrValidation error behavior on
malformed JSON.
🪄 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: c87f24c0-be2a-44a6-820a-f82f562fb80f

📥 Commits

Reviewing files that changed from the base of the PR and between 07765cd and 0f3be77.

📒 Files selected for processing (7)
  • shortcuts/task/shortcuts.go
  • shortcuts/task/task_body_test.go
  • shortcuts/task/task_query_helpers.go
  • shortcuts/task/task_query_helpers_test.go
  • shortcuts/task/task_update.go
  • shortcuts/task/task_util.go
  • shortcuts/task/task_util_test.go
✅ Files skipped from review due to trivial changes (2)
  • shortcuts/task/task_util_test.go
  • shortcuts/task/task_query_helpers.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • shortcuts/task/task_util.go
  • shortcuts/task/task_body_test.go
  • shortcuts/task/task_query_helpers_test.go

Comment thread shortcuts/task/task_update.go

@Zhang-986 Zhang-986 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

tengchengwei
tengchengwei previously approved these changes May 6, 2026
@codecov

codecov Bot commented May 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 42.85714% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.14%. Comparing base (7fb71c6) to head (8221661).
⚠️ Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
shortcuts/task/task_query_helpers.go 33.33% 4 Missing ⚠️
shortcuts/task/shortcuts.go 0.00% 2 Missing ⚠️
shortcuts/task/task_update.go 75.00% 1 Missing ⚠️
shortcuts/task/task_util.go 50.00% 1 Missing ⚠️

❌ Your patch check has failed because the patch coverage (42.85%) is below the target coverage (60.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #740      +/-   ##
==========================================
+ Coverage   64.96%   65.14%   +0.18%     
==========================================
  Files         502      503       +1     
  Lines       46224    46576     +352     
==========================================
+ Hits        30030    30344     +314     
- Misses      13583    13592       +9     
- Partials     2611     2640      +29     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@8221661091fa8159d405524254b0ea16e15ee21d

🧩 Skill update

npx skills add Zhang-986/cli#fix/task-structured-errors -y -g

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 (2)
shortcuts/task/shortcuts.go (2)

100-109: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

--data null causes a nil-map panic in buildTaskCreateBody.

json.Unmarshal([]byte("null"), &body) returns nil error but sets body to nil. Line 102 only guards the error path; the success path with JSON null bypasses it, leaving body == nil. The assignment body["summary"] = summary at Line 108 then panics at runtime.

Same root cause as the flagged issue in buildTaskUpdateBody.

🐛 Proposed fix
 	if dataStr := runtime.Str("data"); dataStr != "" {
 		if err := json.Unmarshal([]byte(dataStr), &body); err != nil {
 			return nil, output.ErrValidation("--data must be a valid JSON object: %v", err)
 		}
+		if body == nil {
+			return nil, output.ErrValidation("--data must be a non-null JSON object")
+		}
 	}
🤖 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/task/shortcuts.go` around lines 100 - 109, buildTaskCreateBody can
receive JSON "null" which json.Unmarshal([]byte(dataStr), &body) accepts but
leaves body == nil, causing a panic when later assigning body["summary"]; update
buildTaskCreateBody (and mirror the same pattern used in buildTaskUpdateBody) to
check if body == nil after unmarshalling and if so initialize it with body =
make(map[string]interface{}) (or return a validation error if you prefer to
forbid null), ensuring subsequent assignments like body["summary"] are safe.

186-190: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validation errors from buildTaskCreateBody are double-wrapped via WrapTaskError.

Line 189 passes buildTaskCreateBody's *output.ExitError into WrapTaskError(ErrCodeTaskInvalidParams, err.Error(), "create task"), which produces a second ExitError. The structured detail (type, hint, code) from the original ErrValidation is discarded and replaced by the generic task-params entry in taskErrorMap. This inconsistency doesn't occur in UpdateTask.Execute (Line 52–55 of task_update.go) — update returns the builder's error directly.

Verify whether CreateTask.Execute should propagate the builder error directly, as UpdateTask already does.

🛠️ Proposed fix
 	body, err := buildTaskCreateBody(runtime)
 	if err != nil {
-		return WrapTaskError(ErrCodeTaskInvalidParams, err.Error(), "create task")
+		return err
 	}
🤖 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/task/shortcuts.go` around lines 186 - 190, The Create task Execute
handler is double-wrapping validation errors from buildTaskCreateBody by calling
WrapTaskError(ErrCodeTaskInvalidParams, err.Error(), "create task"), which
discards the original *output.ExitError structured details; change Execute in
the create task (the Execute func that calls buildTaskCreateBody) to return the
builder error directly (i.e., return err) instead of wrapping it so structured
validation errors from buildTaskCreateBody propagate (do not call WrapTaskError
for errors returned from buildTaskCreateBody); keep
WrapTaskError(ErrCodeTaskInvalidParams, ...) only for genuine new wrapping cases
where you are creating a new task-level error.
♻️ Duplicate comments (2)
shortcuts/task/task_util_test.go (1)

23-62: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

wantSubstr is still defined but never asserted.

The field wantSubstr (Line 29) and its value "invalid relative time format" (Line 36) are populated but the assertion loop never checks err.Error() or exitErr.Detail.Message against it, leaving a message-regression gap.

🛠️ Proposed fix
 import (
 	"errors"
+	"strings"
 	"testing"
 		if exitErr.Detail.Type != tt.wantType {
 			t.Errorf("error type = %q, want %q", exitErr.Detail.Type, tt.wantType)
 		}
+		if tt.wantSubstr != "" && !strings.Contains(exitErr.Detail.Message, tt.wantSubstr) {
+			t.Errorf("error message = %q, want substring %q", exitErr.Detail.Message, tt.wantSubstr)
+		}
 	})
🤖 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/task/task_util_test.go` around lines 23 - 62, The test
TestParseRelativeTime_StructuredErrors populates wantSubstr but never asserts
it; update the table-driven test loop to assert that the returned error message
contains tt.wantSubstr by checking either exitErr.Detail.Message (if non-nil) or
err.Error() as a fallback after calling parseRelativeTime, and fail the test
with t.Errorf when the substring is not found; reference parseRelativeTime and
exitErr.Detail.Message in your assertion so the test covers the expected message
regression.
shortcuts/task/task_update.go (1)

134-141: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

--data null still panics: nil map write at Line 145.

json.Unmarshal([]byte("null"), &taskObj) silently sets taskObj to nil (valid JSON, no error returned). The range taskObj on Line 139 is safe (nil-map range is a no-op), but the subsequent taskObj["summary"] = summary at Line 145 panics on a nil map.

🐛 Proposed fix
 	if dataStr := runtime.Str("data"); dataStr != "" {
 		if err := json.Unmarshal([]byte(dataStr), &taskObj); err != nil {
 			return nil, output.ErrValidation("--data must be a valid JSON object: %v", err)
 		}
+		if taskObj == nil {
+			return nil, output.ErrValidation("--data must be a non-null JSON object")
+		}
 		for k := range taskObj {
🤖 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/task/task_update.go` around lines 134 - 141, The code unmarshals
runtime.Str("data") into taskObj which can become a nil map when the JSON is
"null", causing a panic when later writing taskObj["summary"] in the update
flow; after calling json.Unmarshal in the block that reads runtime.Str("data"),
check if taskObj == nil and if so initialize it to an empty map (e.g.,
make(map[string]interface{})) before iterating and before any writes, and then
continue building updateFields and assigning summary—refer to taskObj,
updateFields, json.Unmarshal and runtime.Str in task_update.go to locate the
changes.
🤖 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/task/task_query_helpers_test.go`:
- Around line 278-286: The reversed-range test branch inside the
parseTimeRangeRFC3339 test is missing the assertion that the ExitError detail
type equals "validation"; update the block handling tt.name == "reversed range
fails fast" in shortcuts/task/task_query_helpers_test.go to mirror
parseTimeRangeMillis by asserting exitErr.Detail.Type == "validation" (in
addition to the existing errors.As and exitErr.Code checks) so the error detail
type is validated for parseTimeRangeRFC3339 as well.

---

Outside diff comments:
In `@shortcuts/task/shortcuts.go`:
- Around line 100-109: buildTaskCreateBody can receive JSON "null" which
json.Unmarshal([]byte(dataStr), &body) accepts but leaves body == nil, causing a
panic when later assigning body["summary"]; update buildTaskCreateBody (and
mirror the same pattern used in buildTaskUpdateBody) to check if body == nil
after unmarshalling and if so initialize it with body =
make(map[string]interface{}) (or return a validation error if you prefer to
forbid null), ensuring subsequent assignments like body["summary"] are safe.
- Around line 186-190: The Create task Execute handler is double-wrapping
validation errors from buildTaskCreateBody by calling
WrapTaskError(ErrCodeTaskInvalidParams, err.Error(), "create task"), which
discards the original *output.ExitError structured details; change Execute in
the create task (the Execute func that calls buildTaskCreateBody) to return the
builder error directly (i.e., return err) instead of wrapping it so structured
validation errors from buildTaskCreateBody propagate (do not call WrapTaskError
for errors returned from buildTaskCreateBody); keep
WrapTaskError(ErrCodeTaskInvalidParams, ...) only for genuine new wrapping cases
where you are creating a new task-level error.

---

Duplicate comments:
In `@shortcuts/task/task_update.go`:
- Around line 134-141: The code unmarshals runtime.Str("data") into taskObj
which can become a nil map when the JSON is "null", causing a panic when later
writing taskObj["summary"] in the update flow; after calling json.Unmarshal in
the block that reads runtime.Str("data"), check if taskObj == nil and if so
initialize it to an empty map (e.g., make(map[string]interface{})) before
iterating and before any writes, and then continue building updateFields and
assigning summary—refer to taskObj, updateFields, json.Unmarshal and runtime.Str
in task_update.go to locate the changes.

In `@shortcuts/task/task_util_test.go`:
- Around line 23-62: The test TestParseRelativeTime_StructuredErrors populates
wantSubstr but never asserts it; update the table-driven test loop to assert
that the returned error message contains tt.wantSubstr by checking either
exitErr.Detail.Message (if non-nil) or err.Error() as a fallback after calling
parseRelativeTime, and fail the test with t.Errorf when the substring is not
found; reference parseRelativeTime and exitErr.Detail.Message in your assertion
so the test covers the expected message regression.
🪄 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: 52ed80b1-c2cf-4d8c-812f-39b0dc6d2abe

📥 Commits

Reviewing files that changed from the base of the PR and between 0f3be77 and 8221661.

📒 Files selected for processing (7)
  • shortcuts/task/shortcuts.go
  • shortcuts/task/task_body_test.go
  • shortcuts/task/task_query_helpers.go
  • shortcuts/task/task_query_helpers_test.go
  • shortcuts/task/task_update.go
  • shortcuts/task/task_util.go
  • shortcuts/task/task_util_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • shortcuts/task/task_body_test.go

Comment thread shortcuts/task/task_query_helpers_test.go

@Zhang-986 Zhang-986 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@zero-my
zero-my merged commit b65147f into larksuite:main May 6, 2026
17 of 18 checks passed
@liangshuo-1 liangshuo-1 mentioned this pull request May 7, 2026
2 tasks
tuxedomm pushed a commit to zhumiaoxin/cli that referenced this pull request Jun 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/task PR touches the task domain size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants