feat(calendar): typed error envelopes for validation/internal errors#1232
feat(calendar): typed error envelopes for validation/internal errors#1232evandance wants to merge 1 commit into
Conversation
Calendar commands now surface validation and internal errors as structured, typed error envelopes with consistent exit codes and a machine-readable shape, so callers (and AI agents) can reliably tell bad input apart from internal faults. API-response error paths keep the existing envelope for now and will move to the typed shape together with the typed API-call path.
📝 WalkthroughWalkthroughThis PR migrates error handling across seven calendar shortcut commands from legacy ChangesCalendar Error Handling Migration to Typed Errors
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
🚀 PR Preview Install Guide🧰 CLI updatenpm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@c4c0438015798b18f1745a69167fde4343f89907🧩 Skill updatenpx skills add larksuite/cli#feat/errs-migrate-calendar -y -g |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1232 +/- ##
==========================================
+ Coverage 69.22% 69.27% +0.04%
==========================================
Files 635 635
Lines 59687 59691 +4
==========================================
+ Hits 41320 41352 +32
+ Misses 15033 15020 -13
+ Partials 3334 3319 -15 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
shortcuts/calendar/calendar_create.go (1)
39-68: ⚡ Quick winConsider adding parameter context to parseAttendees errors.
The
parseAttendeesfunction returns typed validation errors (line 64) but does not include.WithParam(...)because it's called from multiple contexts (--attendee-idsin create,--add-attendee-idsin update). To preserve parameter attribution in the final error envelope, consider one of:
- Add a
paramName stringargument toparseAttendeesand call.WithParam(paramName)on line 64- Return the error as-is and let callers add the param via type assertion if needed
This would align with the PR's goal of structured parameter binding in validation errors.
🤖 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/calendar/calendar_create.go` around lines 39 - 68, parseAttendees currently returns a typed validation error without parameter context; change its signature to parseAttendees(attendeesStr string, currentUserId string, paramName string) and, where you construct the validation error in the default case, call .WithParam(paramName) on the errs.NewValidationError result; then update callers (the create path using "--attendee-ids" and the update path using "--add-attendee-ids") to pass the appropriate param name so the final error envelope preserves parameter attribution.
🤖 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/calendar/calendar_create.go`:
- Around line 217-220: The code currently wraps the typed *errs.ValidationError
returned by parseAttendees(attendeesStr, currentUserId) into a new
errs.NewValidationError, losing the original error type and nesting messages;
instead, return the parseAttendees error directly, and if you need parameter
context call WithParam("--attendee-ids") on the returned error via a type
assertion (e.g., if ve, ok := err.(*errs.ValidationError); ok { return
ve.WithParam("--attendee-ids") } else { return err }), or modify parseAttendees
to accept the parameter name so it can produce a validation error with the param
already set.
In `@shortcuts/calendar/calendar_update.go`:
- Around line 327-330: The code in calendar_update.go is wrapping the typed
*errs.ValidationError from parseAttendees into a new errs.NewValidationError
which loses the original type; change this to return the original error directly
(return err) or, if you need parameter context, type-assert err to
*errs.ValidationError and call .WithParam("--add-attendee-ids") before
returning, or alternatively update parseAttendees to accept a parameterName and
set the param there; specifically modify the block around parseAttendees(addStr,
"") to avoid creating a new ValidationError and preserve the original error
type.
---
Nitpick comments:
In `@shortcuts/calendar/calendar_create.go`:
- Around line 39-68: parseAttendees currently returns a typed validation error
without parameter context; change its signature to parseAttendees(attendeesStr
string, currentUserId string, paramName string) and, where you construct the
validation error in the default case, call .WithParam(paramName) on the
errs.NewValidationError result; then update callers (the create path using
"--attendee-ids" and the update path using "--add-attendee-ids") to pass the
appropriate param name so the final error envelope preserves parameter
attribution.
🪄 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: 795dec8c-fecd-4e85-a2e1-98f9a42a38de
📒 Files selected for processing (8)
shortcuts/calendar/calendar_agenda.goshortcuts/calendar/calendar_create.goshortcuts/calendar/calendar_freebusy.goshortcuts/calendar/calendar_room_find.goshortcuts/calendar/calendar_rsvp.goshortcuts/calendar/calendar_suggestion.goshortcuts/calendar/calendar_test.goshortcuts/calendar/calendar_update.go
| attendees, err := parseAttendees(attendeesStr, currentUserId) | ||
| if err != nil { | ||
| return output.ErrValidation("invalid attendee id: %v", err) | ||
| return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid attendee id: %v", err) | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Avoid wrapping typed validation errors.
Line 219 wraps the typed *errs.ValidationError returned by parseAttendees (line 64) in a new validation error, which loses the original error's typed structure and creates redundant message nesting ("invalid attendee id: unsupported attendee id format: X").
Return the error directly instead:
attendees, err := parseAttendees(attendeesStr, currentUserId)
if err != nil {
- return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid attendee id: %v", err)
+ return err
}If parameter context is needed, add .WithParam("--attendee-ids") via type assertion or modify parseAttendees to accept the parameter name (see suggestion on lines 39-68).
📝 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.
| attendees, err := parseAttendees(attendeesStr, currentUserId) | |
| if err != nil { | |
| return output.ErrValidation("invalid attendee id: %v", err) | |
| return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid attendee id: %v", err) | |
| } | |
| attendees, err := parseAttendees(attendeesStr, currentUserId) | |
| if err != nil { | |
| 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/calendar/calendar_create.go` around lines 217 - 220, The code
currently wraps the typed *errs.ValidationError returned by
parseAttendees(attendeesStr, currentUserId) into a new errs.NewValidationError,
losing the original error type and nesting messages; instead, return the
parseAttendees error directly, and if you need parameter context call
WithParam("--attendee-ids") on the returned error via a type assertion (e.g., if
ve, ok := err.(*errs.ValidationError); ok { return
ve.WithParam("--attendee-ids") } else { return err }), or modify parseAttendees
to accept the parameter name so it can produce a validation error with the param
already set.
| attendees, err := parseAttendees(addStr, "") | ||
| if err != nil { | ||
| return output.ErrValidation("invalid attendee id: %v", err) | ||
| return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid attendee id: %v", err) | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Avoid wrapping typed validation errors.
Line 329 wraps the typed *errs.ValidationError returned by parseAttendees (calendar_create.go line 64) in a new validation error, which loses the original error's typed structure. Return the error directly:
attendees, err := parseAttendees(addStr, "")
if err != nil {
- return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid attendee id: %v", err)
+ return err
}If parameter context is needed, add .WithParam("--add-attendee-ids") via type assertion or modify parseAttendees to accept the parameter name (see suggestion in calendar_create.go lines 39-68).
📝 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.
| attendees, err := parseAttendees(addStr, "") | |
| if err != nil { | |
| return output.ErrValidation("invalid attendee id: %v", err) | |
| return errs.NewValidationError(errs.SubtypeInvalidArgument, "invalid attendee id: %v", err) | |
| } | |
| attendees, err := parseAttendees(addStr, "") | |
| if err != nil { | |
| 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/calendar/calendar_update.go` around lines 327 - 330, The code in
calendar_update.go is wrapping the typed *errs.ValidationError from
parseAttendees into a new errs.NewValidationError which loses the original type;
change this to return the original error directly (return err) or, if you need
parameter context, type-assert err to *errs.ValidationError and call
.WithParam("--add-attendee-ids") before returning, or alternatively update
parseAttendees to accept a parameterName and set the param there; specifically
modify the block around parseAttendees(addStr, "") to avoid creating a new
ValidationError and preserve the original error type.
Summary
Calendar commands now emit structured, typed error envelopes for input-validation and internal failures, replacing the previous legacy/generic errors. Callers — including AI agents — get consistent exit codes and a machine-readable error shape, so "you passed bad input" is reliably distinguishable from "something failed internally".
API-response error paths (the handlers that interpret a calendar API response) keep the existing error envelope for now; they are marked with TODOs and will move to the typed shape together with the typed API-call path, to avoid leaving a half-typed API layer in this change.
Changes
+agenda,+create,+freebusy,+rsvp,+room-find,+suggestion, and+updatenow returns typed validation errors with the offending flag attributed.+room-find/+suggestionAPI responses are classified into typed API-error envelopes via the shared classifier. The success payload is no longer copied into the error detail (it was previously included there).Test Plan
go build ./...go vet ./shortcuts/calendar/...go test ./shortcuts/calendar/...— all pass (new typed-shape tests + unchanged existing tests)gofmt -l shortcuts/calendar/— cleanRelated Issues
Part of the ongoing effort to give CLI errors a typed, machine-readable envelope across domains. No linked issue.
Summary by CodeRabbit
Bug Fixes
Tests