Skip to content

feat(slides): emit typed error envelopes across the slides domain#1349

Merged
evandance merged 1 commit into
mainfrom
feat/errs-migrate-slides
Jun 10, 2026
Merged

feat(slides): emit typed error envelopes across the slides domain#1349
evandance merged 1 commit into
mainfrom
feat/errs-migrate-slides

Conversation

@evandance

@evandance evandance commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Migrates typed error envelopes across the Slides shortcut domain. Scope is limited to shortcuts/slides, Slides error-contract guards, and Slides guard tests.

Changes

  • Converts Slides presentation reference, create, media upload, replace, API, network, file, and invalid-response failures to typed errs.* envelopes.
  • Preserves structured params for --presentation, --slides, --file, --slide-id, and --parts validation.
  • Adds Slides coverage to .golangci.yml and lint/errscontract so legacy envelopes and common helpers cannot regress.

Test Plan

  • gofmt -l <changed go files> produced no output
  • go vet ./shortcuts/slides/...
  • go test ./shortcuts/slides/...
  • go test -C lint ./...
  • go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 run --new-from-rev=origin/main ./shortcuts/slides/...
  • go run -C lint . ..
  • go build ./...

Related Issues

  • None

Summary by CodeRabbit

  • Bug Fixes

    • Standardized and clarified slide-related error messages with explicit flag/parameter attribution (--slides, --file, --slide-id, --parts, --presentation).
    • Validation now consistently reports structured validation errors for invalid JSON, size limits, missing files, invalid IDs/parts, and unsupported references.
    • Improved partial-upload recovery hints and clearer feedback on upload and API failures.
  • Refactor

    • Error handling and API calls standardized to produce consistent, typed errors and preserve original causes for better diagnostics.
  • Tests

    • Expanded/added tests to cover validation, placeholder uploads, error hinting, and error-class preservation.
  • Chores

    • Linter rules updated to include slides shortcuts in migrated-path checks.

@evandance evandance added size/M Single-domain feat or fix with limited business impact domain/ccm PR touches the ccm domain feature labels Jun 9, 2026
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Migrate shortcuts/slides/ to typed errs: extend lint rules, add slides error helpers, convert shared presentation helpers and slides shortcuts to typed API calls and typed errs errors, and update/add tests to assert on typed error problems and Param metadata.

Changes

Slides shortcuts errs migration

Layer / File(s) Summary
Linter configuration and rules enforcement
.golangci.yml, lint/errscontract/rule_no_legacy_*.go, lint/errscontract/rules_test.go
Extend forbidigo path-except patterns to include shortcuts/slides/; add slides path to migrated-path rule lists and a test covering aliased imports and function-value legacy helper usage.
Shared presentation helpers migration
shortcuts/slides/helpers.go
parsePresentationRef, resolvePresentationID, and ensureXMLRootID now return typed errs validation/internal errors and use runtime.CallAPITyped where applicable.
SlidesCreate shortcut migration and tests
shortcuts/slides/slides_create.go, shortcuts/slides/slides_create_test.go
Validate and Execute use errs.NewValidationError and slidesInputStatError for JSON/count/file checks, switch to CallAPITyped, return typed internal error for missing xml_presentation_id, preserve typed causes across uploads, and update tests to assert on structured errs problems and params.
Slides error translation utilities
shortcuts/slides/slides_errors.go, shortcuts/slides/slides_errors_test.go
Add slidesInputStatError to map file-stat errors into *errs.ValidationError with param metadata, and appendSlidesProgressHint to append or wrap errors with orchestration progress hints; tests verify typed preservation and hint behavior.
SlidesMediaUpload shortcut migration and tests
shortcuts/slides/slides_media_upload.go, shortcuts/slides/slides_media_upload_test.go
Replace legacy output/common error returns with slidesInputStatError and errs.NewValidationError(--file) for missing/non-regular/oversize file cases; tests assert *errs.ValidationError with Param == "--file".
SlidesReplaceSlide shortcut migration and tests
shortcuts/slides/slides_replace_slide.go, shortcuts/slides/slides_replace_slide_test.go
--slide-id, --parts parsing/validation, and part invariants now return errs.NewValidationError with param metadata; API calls use CallAPITyped; enrichSlidesReplaceError uses errs.ProblemOf; tests assert on typed problem Code, Hint, and validation Param.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • larksuite/cli#1346: Both PRs modify the same error-contract linting rules (migratedCommonHelperPaths / migratedEnvelopePaths) and the rules_test.go matrices—expanding them for different shortcut domains (shortcuts/slides/ vs shortcuts/doc/).
  • larksuite/cli#1234: Extends the migrated-path allowlists in lint/errscontract rules for additional shortcut prefixes, similar to this change.
  • larksuite/cli#1248: Also adjusts errscontract migrated-path coverage and forbidigo matcher adjustments for another shortcut domain.

Suggested labels

domain/ccm, size/L

Suggested reviewers

  • kongenpei
  • syh-cpdsss

"I’m a rabbit in the codewood, nibbling old error trails,
I stitch hints to problems and leave typed breadcrumb rails.
No more bare wraps or legacy cries, just structured errs that sing,
Slides march on with clearer faults, and tests now dance and spring.
🐇✨"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.92% 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 accurately summarizes the main change: migrating the slides domain to use typed error envelopes from the errs package.
Description check ✅ Passed The description follows the template structure with Summary, Changes, Test Plan, and Related Issues sections; all required information is present and comprehensive.
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
  • Commit unit tests in branch feat/errs-migrate-slides

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.

@github-actions github-actions Bot removed the domain/ccm PR touches the ccm domain label Jun 9, 2026
@evandance evandance added the domain/ccm PR touches the ccm domain label Jun 9, 2026
@github-actions github-actions Bot removed the domain/ccm PR touches the ccm domain label Jun 9, 2026

@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.

🧹 Nitpick comments (7)
shortcuts/slides/slides_replace_slide.go (6)

60-60: ⚡ Quick win

Consider adding .WithParam("--slide-id") for consistency.

Other validation errors in the migration attach the related flag via .WithParam() (e.g., slides_create.go:48, slides_media_upload.go:92). This helps structured error consumers identify which parameter failed.

Suggested enhancement
-return errs.NewValidationError(errs.SubtypeInvalidArgument, "--slide-id cannot be empty")
+return errs.NewValidationError(errs.SubtypeInvalidArgument, "--slide-id cannot be empty").WithParam("--slide-id")
🤖 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/slides/slides_replace_slide.go` at line 60, The validation error
returned uses errs.NewValidationError(errs.SubtypeInvalidArgument, "--slide-id
cannot be empty") but is missing the structured parameter name; update the
return to chain .WithParam("--slide-id") on the error (i.e., locate the call to
errs.NewValidationError in slides_replace_slide.go and append
.WithParam("--slide-id") to the returned error) so it matches other validations
like slides_create.go and slides_media_upload.go.

207-207: ⚡ Quick win

Consider adding .WithParam("--parts") for consistency.

This validation error should attach the parameter like other similar errors in the migration.

Suggested enhancement
-return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts invalid JSON, must be an array of objects: %v", err)
+return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts invalid JSON, must be an array of objects: %v", err).WithParam("--parts")
🤖 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/slides/slides_replace_slide.go` at line 207, The validation error
created by errs.NewValidationError in slides_replace_slide.go should attach the
parameter for consistency; update the return that currently calls
errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts invalid JSON, must
be an array of objects: %v", err) to chain .WithParam("--parts") on the error
before returning so the parameter name is included (locate the
NewValidationError call in the ReplaceSlide/slide replacement handling and add
.WithParam("--parts")).

203-203: ⚡ Quick win

Consider adding .WithParam("--parts") for consistency.

Similar to the --slide-id validation and other migrations in this PR, attaching the parameter helps structured error consumers.

Suggested enhancement
-return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts cannot be empty")
+return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts cannot be empty").WithParam("--parts")
🤖 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/slides/slides_replace_slide.go` at line 203, The validation error
return in slides_replace_slide.go uses
errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts cannot be empty")
but omits the parameter metadata; update the return to attach the parameter by
chaining .WithParam("--parts") on the error (i.e., call
errs.NewValidationError(...).WithParam("--parts")) so it matches the other
validations like the --slide-id case and provides structured param info for
consumers.

215-243: ⚡ Quick win

Consider adding .WithParam("--parts") to all field type validation errors.

These five type-assertion errors (action, replacement, block_id, insertion, insert_before_block_id) should attach the parameter for consistency with other validation errors in this migration.

Suggested enhancement
 if v, ok := m["action"]; ok {
     s, ok := v.(string)
     if !ok {
-        return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts[%d].action must be a string", i)
+        return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts[%d].action must be a string", i).WithParam("--parts")
     }
     p.Action = s
 }

Apply the same pattern to the remaining four field validations (replacement, block_id, insertion, insert_before_block_id).

🤖 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/slides/slides_replace_slide.go` around lines 215 - 243, The
validation error calls in slides_replace_slide.go for the parts parsing (fields
action, replacement, block_id, insertion, insert_before_block_id) should include
the parameter context; update each errs.NewValidationError invocation in the
parts-parsing logic (the block that assigns to p.Action, p.Replacement,
p.BlockID, p.Insertion, p.InsertBeforeBlockID) to chain .WithParam("--parts") so
every type-assertion error attaches the "--parts" parameter consistently.

330-330: ⚡ Quick win

Consider adding .WithParam("--parts") for consistency.

This error wraps a replacement XML parsing failure and should attach the parameter like other --parts validations.

Suggested enhancement
-return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts[%d].replacement: %v", i, err).WithCause(err)
+return nil, errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts[%d].replacement: %v", i, err).WithCause(err).WithParam("--parts")
🤖 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/slides/slides_replace_slide.go` at line 330, The validation error
returned from errs.NewValidationError for the replacement XML parse should
include the parameter name for consistency; modify the error construction at the
return (the call that currently does
errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts[%d].replacement:
%v", i, err).WithCause(err)) to also call .WithParam("--parts") (e.g., chain
.WithParam("--parts") before/after .WithCause(err)) so the error includes the
parameter metadata while preserving the original cause.

283-309: ⚡ Quick win

Consider adding .WithParam("--parts") to all validation errors in this function.

For consistency with the migration pattern, all eight validation errors in validateReplaceParts should attach the parameter.

Suggested enhancement

Add .WithParam("--parts") to each of the eight errs.NewValidationError calls in this function (lines 283, 286, 292, 295, 299, 305, 307, 309).

Example for line 283:

-return errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts must contain at least 1 item")
+return errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts must contain at least 1 item").WithParam("--parts")
🤖 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/slides/slides_replace_slide.go` around lines 283 - 309, In
validateReplaceParts, update every errs.NewValidationError return to chain
.WithParam("--parts") so all eight validation errors include the parameter
context; locate the NewValidationError calls inside validateReplaceParts (the
ones checking len(parts), maxReplaceParts, and each switch case for p.Action
including block_replace, block_insert, str_replace, empty action, and default)
and append .WithParam("--parts") to each returned error.
shortcuts/slides/helpers.go (1)

105-105: ⚡ Quick win

Consider using an internal error for this defensive programming case.

The ref.Kind field is set only by parsePresentationRef (lines 44, 47, 57), which returns exclusively "slides" or "wiki". This default case should never execute during normal operation—it's a defensive guard against programming errors (e.g., a future code change that adds a new kind without updating this function).

A validation error implies user input is wrong, but the user never directly sets ref.Kind. An internal error would more accurately reflect that this represents a programming bug rather than invalid user input.

Suggested improvement
-	return "", errs.NewValidationError(errs.SubtypeInvalidArgument, "unsupported presentation ref kind %q", ref.Kind)
+	return "", errs.NewInternalError(errs.SubtypeSDKError, "unsupported presentation ref kind %q (programming error)", ref.Kind)
🤖 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/slides/helpers.go` at line 105, The default branch returning a
validation error for unsupported presentation ref kind should be an
internal/programming error because ref.Kind is set only by parsePresentationRef
(which yields "slides" or "wiki"); change the error created in that return (the
one referencing ref.Kind) from
errs.NewValidationError(errs.SubtypeInvalidArgument, ...) to the appropriate
internal error constructor (e.g., errs.NewInternalError or the codebase's
internal error helper) so this impossible/default case is reported as an
internal/programming error rather than user input validation failure.
🤖 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.

Nitpick comments:
In `@shortcuts/slides/helpers.go`:
- Line 105: The default branch returning a validation error for unsupported
presentation ref kind should be an internal/programming error because ref.Kind
is set only by parsePresentationRef (which yields "slides" or "wiki"); change
the error created in that return (the one referencing ref.Kind) from
errs.NewValidationError(errs.SubtypeInvalidArgument, ...) to the appropriate
internal error constructor (e.g., errs.NewInternalError or the codebase's
internal error helper) so this impossible/default case is reported as an
internal/programming error rather than user input validation failure.

In `@shortcuts/slides/slides_replace_slide.go`:
- Line 60: The validation error returned uses
errs.NewValidationError(errs.SubtypeInvalidArgument, "--slide-id cannot be
empty") but is missing the structured parameter name; update the return to chain
.WithParam("--slide-id") on the error (i.e., locate the call to
errs.NewValidationError in slides_replace_slide.go and append
.WithParam("--slide-id") to the returned error) so it matches other validations
like slides_create.go and slides_media_upload.go.
- Line 207: The validation error created by errs.NewValidationError in
slides_replace_slide.go should attach the parameter for consistency; update the
return that currently calls errs.NewValidationError(errs.SubtypeInvalidArgument,
"--parts invalid JSON, must be an array of objects: %v", err) to chain
.WithParam("--parts") on the error before returning so the parameter name is
included (locate the NewValidationError call in the ReplaceSlide/slide
replacement handling and add .WithParam("--parts")).
- Line 203: The validation error return in slides_replace_slide.go uses
errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts cannot be empty")
but omits the parameter metadata; update the return to attach the parameter by
chaining .WithParam("--parts") on the error (i.e., call
errs.NewValidationError(...).WithParam("--parts")) so it matches the other
validations like the --slide-id case and provides structured param info for
consumers.
- Around line 215-243: The validation error calls in slides_replace_slide.go for
the parts parsing (fields action, replacement, block_id, insertion,
insert_before_block_id) should include the parameter context; update each
errs.NewValidationError invocation in the parts-parsing logic (the block that
assigns to p.Action, p.Replacement, p.BlockID, p.Insertion,
p.InsertBeforeBlockID) to chain .WithParam("--parts") so every type-assertion
error attaches the "--parts" parameter consistently.
- Line 330: The validation error returned from errs.NewValidationError for the
replacement XML parse should include the parameter name for consistency; modify
the error construction at the return (the call that currently does
errs.NewValidationError(errs.SubtypeInvalidArgument, "--parts[%d].replacement:
%v", i, err).WithCause(err)) to also call .WithParam("--parts") (e.g., chain
.WithParam("--parts") before/after .WithCause(err)) so the error includes the
parameter metadata while preserving the original cause.
- Around line 283-309: In validateReplaceParts, update every
errs.NewValidationError return to chain .WithParam("--parts") so all eight
validation errors include the parameter context; locate the NewValidationError
calls inside validateReplaceParts (the ones checking len(parts),
maxReplaceParts, and each switch case for p.Action including block_replace,
block_insert, str_replace, empty action, and default) and append
.WithParam("--parts") to each returned error.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3143418a-7fbf-4e56-9e2c-497dd7b0b082

📥 Commits

Reviewing files that changed from the base of the PR and between 03ea6e7 and 3e0b96c.

📒 Files selected for processing (11)
  • .golangci.yml
  • lint/errscontract/rule_no_legacy_common_helper_call.go
  • lint/errscontract/rule_no_legacy_envelope_literal.go
  • lint/errscontract/rules_test.go
  • shortcuts/slides/helpers.go
  • shortcuts/slides/slides_create.go
  • shortcuts/slides/slides_create_test.go
  • shortcuts/slides/slides_errors.go
  • shortcuts/slides/slides_media_upload.go
  • shortcuts/slides/slides_replace_slide.go
  • shortcuts/slides/slides_replace_slide_test.go

@codecov

codecov Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 79.10448% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.97%. Comparing base (b07be60) to head (ae8aa84).

Files with missing lines Patch % Lines
shortcuts/slides/slides_create.go 50.00% 7 Missing ⚠️
shortcuts/slides/slides_media_upload.go 20.00% 4 Missing ⚠️
shortcuts/slides/helpers.go 66.66% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1349      +/-   ##
==========================================
+ Coverage   71.96%   71.97%   +0.01%     
==========================================
  Files         695      696       +1     
  Lines       65879    65891      +12     
==========================================
+ Hits        47408    47424      +16     
+ Misses      14814    14811       -3     
+ Partials     3657     3656       -1     

☔ View full report in Codecov by Harness.
📢 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 Jun 9, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#feat/errs-migrate-slides -y -g

@evandance evandance force-pushed the feat/errs-migrate-slides branch from 3e0b96c to 5c16948 Compare June 9, 2026 12:21

@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

🧹 Nitpick comments (1)
shortcuts/slides/slides_replace_slide_test.go (1)

724-730: 💤 Low value

Consider adding an explicit nil check for consistency.

The test correctly uses errors.As to unwrap the *errs.ValidationError and check its Param field. However, for consistency with the established pattern in this file (lines 284-286, 343-345, 631-633, 670-672), consider adding an explicit nil check before the errors.As call:

if err == nil {
    t.Fatalf("expected validation error for %s", tt.name)
}

This would make the failure message more descriptive when the test accidentally passes without producing an error.

🤖 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/slides/slides_replace_slide_test.go` around lines 724 - 730, Add an
explicit nil check before unwrapping the error: ensure that when testing the
ReplaceSlide error path you verify err != nil (e.g., check err == nil and call
t.Fatalf with a message referencing tt.name) before calling errors.As; update
the block that declares var ve *errs.ValidationError and uses errors.As(err,
&ve) to first fail if err is nil, then proceed to errors.As and the subsequent
Param assertion (referencing variables err, ve, tt.wantParam, tt.name).
🤖 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 `@lint/errscontract/rule_no_legacy_common_helper_call.go`:
- Around line 18-20: The entries "cmd/event/", "events/",
"internal/event/consume/", and "shortcuts/event/" were added to the scope in
lint/errscontract/rule_no_legacy_common_helper_call.go but there are no actual
code changes under those paths; update the PR to either (A) clarify in the PR
description that this change is intentional and is a linter-scope/config-only
update (explain why the rule should now cover event paths), or (B) remove those
added prefixes from rule_no_legacy_common_helper_call.go if they were added
unintentionally, ensuring the file's scope matches the intended affected code.

In `@shortcuts/slides/slides_media_upload_test.go`:
- Around line 220-227: The test currently asserts the error is a
*errs.ValidationError and that ve.Param == "--file" but must also assert the
subtype and that the underlying cause was preserved; update the assertion block
(where ve is checked) to verify ve.Subtype == errs.SubtypeInvalidArgument and
that ve.Cause (or the wrapped cause accessible on errs.ValidationError) matches
the original stat error returned by slidesInputStatError (i.e., use errors.Is or
compare the cause returned from slidesInputStatError().WithCause(err) to ensure
WithCause(err) was preserved).

---

Nitpick comments:
In `@shortcuts/slides/slides_replace_slide_test.go`:
- Around line 724-730: Add an explicit nil check before unwrapping the error:
ensure that when testing the ReplaceSlide error path you verify err != nil
(e.g., check err == nil and call t.Fatalf with a message referencing tt.name)
before calling errors.As; update the block that declares var ve
*errs.ValidationError and uses errors.As(err, &ve) to first fail if err is nil,
then proceed to errors.As and the subsequent Param assertion (referencing
variables err, ve, tt.wantParam, tt.name).
🪄 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: 940aa31e-f633-4f5e-bca6-28b8ce972f73

📥 Commits

Reviewing files that changed from the base of the PR and between 3e0b96c and 5c16948.

📒 Files selected for processing (13)
  • .golangci.yml
  • lint/errscontract/rule_no_legacy_common_helper_call.go
  • lint/errscontract/rule_no_legacy_envelope_literal.go
  • lint/errscontract/rules_test.go
  • shortcuts/slides/helpers.go
  • shortcuts/slides/slides_create.go
  • shortcuts/slides/slides_create_test.go
  • shortcuts/slides/slides_errors.go
  • shortcuts/slides/slides_errors_test.go
  • shortcuts/slides/slides_media_upload.go
  • shortcuts/slides/slides_media_upload_test.go
  • shortcuts/slides/slides_replace_slide.go
  • shortcuts/slides/slides_replace_slide_test.go
✅ Files skipped from review due to trivial changes (1)
  • .golangci.yml
🚧 Files skipped from review as they are similar to previous changes (6)
  • lint/errscontract/rules_test.go
  • shortcuts/slides/slides_errors.go
  • shortcuts/slides/slides_media_upload.go
  • shortcuts/slides/slides_create.go
  • shortcuts/slides/helpers.go
  • shortcuts/slides/slides_replace_slide.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.

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: 2

🧹 Nitpick comments (1)
shortcuts/slides/slides_replace_slide_test.go (1)

724-730: 💤 Low value

Consider adding an explicit nil check for consistency.

The test correctly uses errors.As to unwrap the *errs.ValidationError and check its Param field. However, for consistency with the established pattern in this file (lines 284-286, 343-345, 631-633, 670-672), consider adding an explicit nil check before the errors.As call:

if err == nil {
    t.Fatalf("expected validation error for %s", tt.name)
}

This would make the failure message more descriptive when the test accidentally passes without producing an error.

🤖 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/slides/slides_replace_slide_test.go` around lines 724 - 730, Add an
explicit nil check before unwrapping the error: ensure that when testing the
ReplaceSlide error path you verify err != nil (e.g., check err == nil and call
t.Fatalf with a message referencing tt.name) before calling errors.As; update
the block that declares var ve *errs.ValidationError and uses errors.As(err,
&ve) to first fail if err is nil, then proceed to errors.As and the subsequent
Param assertion (referencing variables err, ve, tt.wantParam, tt.name).
🤖 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 `@lint/errscontract/rule_no_legacy_common_helper_call.go`:
- Around line 18-20: The entries "cmd/event/", "events/",
"internal/event/consume/", and "shortcuts/event/" were added to the scope in
lint/errscontract/rule_no_legacy_common_helper_call.go but there are no actual
code changes under those paths; update the PR to either (A) clarify in the PR
description that this change is intentional and is a linter-scope/config-only
update (explain why the rule should now cover event paths), or (B) remove those
added prefixes from rule_no_legacy_common_helper_call.go if they were added
unintentionally, ensuring the file's scope matches the intended affected code.

In `@shortcuts/slides/slides_media_upload_test.go`:
- Around line 220-227: The test currently asserts the error is a
*errs.ValidationError and that ve.Param == "--file" but must also assert the
subtype and that the underlying cause was preserved; update the assertion block
(where ve is checked) to verify ve.Subtype == errs.SubtypeInvalidArgument and
that ve.Cause (or the wrapped cause accessible on errs.ValidationError) matches
the original stat error returned by slidesInputStatError (i.e., use errors.Is or
compare the cause returned from slidesInputStatError().WithCause(err) to ensure
WithCause(err) was preserved).

---

Nitpick comments:
In `@shortcuts/slides/slides_replace_slide_test.go`:
- Around line 724-730: Add an explicit nil check before unwrapping the error:
ensure that when testing the ReplaceSlide error path you verify err != nil
(e.g., check err == nil and call t.Fatalf with a message referencing tt.name)
before calling errors.As; update the block that declares var ve
*errs.ValidationError and uses errors.As(err, &ve) to first fail if err is nil,
then proceed to errors.As and the subsequent Param assertion (referencing
variables err, ve, tt.wantParam, tt.name).
🪄 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: 940aa31e-f633-4f5e-bca6-28b8ce972f73

📥 Commits

Reviewing files that changed from the base of the PR and between 3e0b96c and 5c16948.

📒 Files selected for processing (13)
  • .golangci.yml
  • lint/errscontract/rule_no_legacy_common_helper_call.go
  • lint/errscontract/rule_no_legacy_envelope_literal.go
  • lint/errscontract/rules_test.go
  • shortcuts/slides/helpers.go
  • shortcuts/slides/slides_create.go
  • shortcuts/slides/slides_create_test.go
  • shortcuts/slides/slides_errors.go
  • shortcuts/slides/slides_errors_test.go
  • shortcuts/slides/slides_media_upload.go
  • shortcuts/slides/slides_media_upload_test.go
  • shortcuts/slides/slides_replace_slide.go
  • shortcuts/slides/slides_replace_slide_test.go
✅ Files skipped from review due to trivial changes (1)
  • .golangci.yml
🚧 Files skipped from review as they are similar to previous changes (6)
  • lint/errscontract/rules_test.go
  • shortcuts/slides/slides_errors.go
  • shortcuts/slides/slides_media_upload.go
  • shortcuts/slides/slides_create.go
  • shortcuts/slides/helpers.go
  • shortcuts/slides/slides_replace_slide.go
🛑 Comments failed to post (2)
lint/errscontract/rule_no_legacy_common_helper_call.go (1)

18-20: ⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check if this PR includes event-domain changes beyond linter config

# Check for modified files under event-related paths
git diff --name-only origin/main | grep -E '^(cmd/event/|events/|internal/event/consume/|shortcuts/event/)' || echo "No event-domain file changes found"

Repository: larksuite/cli

Length of output: 92


Adjust scope rationale for added event path prefixes in lint rule (non-code change only)

git diff shows no file changes under cmd/event/, events/, internal/event/consume/, or shortcuts/event/; the new cmd/event/, events/, internal/event/consume/, shortcuts/event/ entries in lint/errscontract/rule_no_legacy_common_helper_call.go (lines 18-20) appear to be linter-scope configuration only. If the PR is intended to be slides-only, clarify in the PR description why this lint rule should cover event paths (or remove the prefixes if unintended).

🤖 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 `@lint/errscontract/rule_no_legacy_common_helper_call.go` around lines 18 - 20,
The entries "cmd/event/", "events/", "internal/event/consume/", and
"shortcuts/event/" were added to the scope in
lint/errscontract/rule_no_legacy_common_helper_call.go but there are no actual
code changes under those paths; update the PR to either (A) clarify in the PR
description that this change is intentional and is a linter-scope/config-only
update (explain why the rule should now cover event paths), or (B) remove those
added prefixes from rule_no_legacy_common_helper_call.go if they were added
unintentionally, ensuring the file's scope matches the intended affected code.
shortcuts/slides/slides_media_upload_test.go (1)

220-227: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Complete the typed error assertion per guidelines.

The typed error check correctly verifies Param == "--file", but per coding guidelines, error-path tests must also assert subtype and cause preservation. The upstream slidesInputStatError helper returns errs.SubtypeInvalidArgument and wraps the underlying error via .WithCause(err).

✅ Proposed additions to complete the migration

Add subtype and cause-preservation checks:

 	var ve *errs.ValidationError
 	if !errors.As(err, &ve) {
 		t.Fatalf("err = %v, want *errs.ValidationError", err)
 	}
 	if ve.Param != "--file" {
 		t.Fatalf("Param = %q, want --file", ve.Param)
 	}
+	if ve.Subtype != errs.SubtypeInvalidArgument {
+		t.Fatalf("Subtype = %v, want SubtypeInvalidArgument", ve.Subtype)
+	}
+	if !errors.Is(err, os.ErrNotExist) && !errors.Is(err, fs.ErrNotExist) {
+		t.Fatalf("error should wrap fs.ErrNotExist for cause preservation, got: %v", err)
+	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.


	var ve *errs.ValidationError
	if !errors.As(err, &ve) {
		t.Fatalf("err = %v, want *errs.ValidationError", err)
	}
	if ve.Param != "--file" {
		t.Fatalf("Param = %q, want --file", ve.Param)
	}
	if ve.Subtype != errs.SubtypeInvalidArgument {
		t.Fatalf("Subtype = %v, want SubtypeInvalidArgument", ve.Subtype)
	}
	if !errors.Is(err, os.ErrNotExist) && !errors.Is(err, fs.ErrNotExist) {
		t.Fatalf("error should wrap fs.ErrNotExist for cause preservation, got: %v", 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/slides/slides_media_upload_test.go` around lines 220 - 227, The
test currently asserts the error is a *errs.ValidationError and that ve.Param ==
"--file" but must also assert the subtype and that the underlying cause was
preserved; update the assertion block (where ve is checked) to verify ve.Subtype
== errs.SubtypeInvalidArgument and that ve.Cause (or the wrapped cause
accessible on errs.ValidationError) matches the original stat error returned by
slidesInputStatError (i.e., use errors.Is or compare the cause returned from
slidesInputStatError().WithCause(err) to ensure WithCause(err) was preserved).

Source: Coding guidelines

@evandance evandance force-pushed the feat/errs-migrate-slides branch 2 times, most recently from e3aae12 to 4ae2809 Compare June 9, 2026 13:31

@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

🤖 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/slides/slides_replace_slide.go`:
- Around line 207-208: The validation error currently formats the JSON decode
error into the message and loses the typed cause; update the return so it does
not embed "%v" with err but instead preserves the original error by calling
.WithCause(err) on the errs.NewValidationError result (keep the human message
like "--parts invalid JSON, must be an array of objects" and retain the existing
.WithParam("--parts")). Specifically modify the expression using
errs.NewValidationError(...) and .WithParam to also chain .WithCause(err) so
errors.Is/unwrapping still work.
- Around line 329-331: The current code always wraps errors from ensureXMLRootID
in a new errs.NewValidationError, which can strip already-typed errs.* metadata;
change the error handling in the replacement parsing loop so that if err is
already a typed errs error you return it unchanged (e.g. type-assert or use the
package's exported typed error interface/marker like errs.Error /
errs.TypedError), otherwise wrap non-typed errors with errs.NewValidationError
as before; check and update the branch around ensureXMLRootID (the block that
currently calls errs.NewValidationError("--parts[%d].replacement: %v", i, err))
to first detect typed errs and return err directly, only constructing a new
validation error for non-errs errors.
🪄 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: 7bc8f222-df65-44b4-b515-567ac2a36290

📥 Commits

Reviewing files that changed from the base of the PR and between e3aae12 and 4ae2809.

📒 Files selected for processing (13)
  • .golangci.yml
  • lint/errscontract/rule_no_legacy_common_helper_call.go
  • lint/errscontract/rule_no_legacy_envelope_literal.go
  • lint/errscontract/rules_test.go
  • shortcuts/slides/helpers.go
  • shortcuts/slides/slides_create.go
  • shortcuts/slides/slides_create_test.go
  • shortcuts/slides/slides_errors.go
  • shortcuts/slides/slides_errors_test.go
  • shortcuts/slides/slides_media_upload.go
  • shortcuts/slides/slides_media_upload_test.go
  • shortcuts/slides/slides_replace_slide.go
  • shortcuts/slides/slides_replace_slide_test.go
✅ Files skipped from review due to trivial changes (1)
  • lint/errscontract/rule_no_legacy_common_helper_call.go
🚧 Files skipped from review as they are similar to previous changes (11)
  • lint/errscontract/rule_no_legacy_envelope_literal.go
  • lint/errscontract/rules_test.go
  • .golangci.yml
  • shortcuts/slides/slides_media_upload.go
  • shortcuts/slides/slides_media_upload_test.go
  • shortcuts/slides/slides_errors_test.go
  • shortcuts/slides/slides_errors.go
  • shortcuts/slides/helpers.go
  • shortcuts/slides/slides_create.go
  • shortcuts/slides/slides_create_test.go
  • shortcuts/slides/slides_replace_slide_test.go

Comment thread shortcuts/slides/slides_replace_slide.go Outdated
Comment thread shortcuts/slides/slides_replace_slide.go
@evandance evandance force-pushed the feat/errs-migrate-slides branch from 4ae2809 to dd0221c Compare June 9, 2026 13:48

@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

🤖 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/slides/slides_errors.go`:
- Line 49: Replace the misclassified subtype in the errs.NewInternalError call:
change the second argument from errs.SubtypeSDKError to errs.SubtypeUnknown so
the fallback unclassified errors are correctly labeled, and ensure the returned
error still chains the original error via .WithCause(err) (you may retain
.WithHint(hint) if the hint is applicable); specifically update the
errs.NewInternalError(...) invocation that currently references
errs.SubtypeSDKError to use errs.SubtypeUnknown and keep .WithCause(err).

In `@shortcuts/slides/slides_replace_slide_test.go`:
- Around line 724-730: Replace the concrete-type cast using errors.As with the
typed-envelope helper errs.ProblemOf: call p := errs.ProblemOf(err), assert p !=
nil and p.Subtype matches the expected validation subtype, then assert p.Param
equals tt.wantParam (instead of casting to *errs.ValidationError and checking
ve.Param). Use the existing tt.wantParam and the error variable err to drive
these assertions and remove the errors.As path.
🪄 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: 59a96c38-2733-475a-9b2f-310729becd05

📥 Commits

Reviewing files that changed from the base of the PR and between 4ae2809 and dd0221c.

📒 Files selected for processing (13)
  • .golangci.yml
  • lint/errscontract/rule_no_legacy_common_helper_call.go
  • lint/errscontract/rule_no_legacy_envelope_literal.go
  • lint/errscontract/rules_test.go
  • shortcuts/slides/helpers.go
  • shortcuts/slides/slides_create.go
  • shortcuts/slides/slides_create_test.go
  • shortcuts/slides/slides_errors.go
  • shortcuts/slides/slides_errors_test.go
  • shortcuts/slides/slides_media_upload.go
  • shortcuts/slides/slides_media_upload_test.go
  • shortcuts/slides/slides_replace_slide.go
  • shortcuts/slides/slides_replace_slide_test.go
✅ Files skipped from review due to trivial changes (1)
  • lint/errscontract/rule_no_legacy_common_helper_call.go
🚧 Files skipped from review as they are similar to previous changes (10)
  • lint/errscontract/rule_no_legacy_envelope_literal.go
  • shortcuts/slides/slides_media_upload_test.go
  • .golangci.yml
  • shortcuts/slides/slides_media_upload.go
  • lint/errscontract/rules_test.go
  • shortcuts/slides/helpers.go
  • shortcuts/slides/slides_errors_test.go
  • shortcuts/slides/slides_replace_slide.go
  • shortcuts/slides/slides_create.go
  • shortcuts/slides/slides_create_test.go

Comment thread shortcuts/slides/slides_errors.go Outdated
Comment thread shortcuts/slides/slides_replace_slide_test.go
@evandance evandance force-pushed the feat/errs-migrate-slides branch from dd0221c to bc3e83b Compare June 9, 2026 14:04
ViperCai
ViperCai previously approved these changes Jun 10, 2026
Emit structured validation, API, network, file, and internal error envelopes for Slides shortcuts so users and agents can recover from failed presentation workflows using stable type, subtype, param, and code fields.

Add Slides domain errscontract and golangci guards to prevent legacy envelope and common helper regressions.
@evandance evandance merged commit 6b48a39 into main Jun 10, 2026
36 of 40 checks passed
@evandance evandance deleted the feat/errs-migrate-slides branch June 10, 2026 06:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants