Skip to content

refactor(src): migrate jira commands to AppError with From<JiraError>#81

Merged
saagpatel merged 1 commit intomasterfrom
codex/refactor/app-error-jira
Apr 22, 2026
Merged

refactor(src): migrate jira commands to AppError with From<JiraError>#81
saagpatel merged 1 commit intomasterfrom
codex/refactor/app-error-jira

Conversation

@saagpatel
Copy link
Copy Markdown
Owner

Summary

Continuation of ADR 0012 migration. 10 Jira Tauri commands → Result<T, AppError> plus a rich From<jira::JiraError> impl in error.rs.

Code mapping via From

JiraError variant AppError code Notes
Request(reqwest::Error) NETWORK_CONNECTION_FAILED retryable
Api(msg) NETWORK_CONNECTION_FAILED + detail
Parse(msg) VALIDATION_INVALID_FORMAT + detail
NotConfigured SECURITY_AUTH_FAILED
AuthFailed SECURITY_AUTH_FAILED retryable via auth_failed()
RateLimited NETWORK_RATE_LIMITED retryable
Timeout NETWORK_TIMEOUT retryable

Each JiraClient call site collapses from .await.map_err(|e| e.to_string())? to .await? — the cleanest migration so far.

Other call-site mappings

  • HTTPS-required refusal → SECURITY_HTTPS_REQUIRED (https_required() constructor)
  • Draft missing response text → NOT_FOUND_DRAFT (draft_not_found())
  • SSRF validation failure → VALIDATION_INVALID_URL (invalid_url())
  • Jira connection not configured → SECURITY_AUTH_FAILED with detail

Compatibility bridging

commands/mod.rs carries a dead-code block (~800 LOC) of 10 duplicate Jira wrappers that shadow jira_commands.rs. Four of them delegate to jira_commands::*_impl and needed a .map_err(|e| e.to_string()) bridge to keep compiling. Full deletion of that block is a separate follow-up task.

Test plan

  • cargo check --all-targets — clean
  • cargo test --lib — 311 pass, 1 ignored
  • cargo test --test command_contracts — 8 pass
  • pnpm tsc --noEmit — clean
  • pnpm test — 67 files, 262 tests pass
  • Frontend audit: only one .catch site touches Jira errors, and it ignores the payload — zero wire-format risk

🤖 Generated with Claude Code

Continue ADR 0012 migration. jira_commands.rs has 10 Tauri commands
(is_jira_configured, get_jira_config, configure_jira, clear_jira_config,
get_jira_ticket, add_jira_comment, push_draft_to_jira,
get_jira_transitions, transition_jira_ticket, post_and_transition).

Added a From<jira::JiraError> impl in error.rs so each JiraClient call
site collapses from .map_err(|e| e.to_string()) to ?-propagation, with
rich code mapping:

- JiraError::Request        -> NETWORK_CONNECTION_FAILED (retryable)
- JiraError::Api            -> NETWORK_CONNECTION_FAILED + detail
- JiraError::Parse          -> VALIDATION_INVALID_FORMAT + detail
- JiraError::NotConfigured  -> SECURITY_AUTH_FAILED
- JiraError::AuthFailed     -> auth_failed() (retryable)
- JiraError::RateLimited    -> NETWORK_RATE_LIMITED (retryable)
- JiraError::Timeout        -> NETWORK_TIMEOUT (retryable)

Other error sites:
- HTTPS-required refusal now carries SECURITY_HTTPS_REQUIRED (the
  https_required() constructor was already defined)
- Draft missing response text -> NOT_FOUND_DRAFT (draft_not_found())
- SSRF validation failure -> VALIDATION_INVALID_URL (invalid_url())
- Jira connection not configured -> SECURITY_AUTH_FAILED + detail

Bridging: commands/mod.rs has an unrelated, unregistered, dead-code
block of 10 duplicate Jira wrappers (~800 LOC) that shadow
jira_commands.rs. Four of them delegate to jira_commands::*_impl and
so must bridge the new AppError back to String with
.map_err(|e| e.to_string()) to keep compiling. The full deletion of
that dead block is spun off as a separate task (it's orthogonal to
the error-type migration).

Verified:
- cargo check --all-targets clean
- cargo test --lib: 311 pass, 1 ignored
- cargo test --test command_contracts: 8 pass
- pnpm tsc --noEmit clean
- pnpm test: 67 files, 262 tests pass
- No frontend Jira error strings are exact-string matched (only one
  .catch site, which ignores the error)
@saagpatel saagpatel merged commit 7a1e3d9 into master Apr 22, 2026
@saagpatel saagpatel deleted the codex/refactor/app-error-jira branch April 22, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants