feat: add structured IPC error types with miette diagnostics#181
Conversation
There was a problem hiding this comment.
Pull request overview
This PR enhances IPC error handling by introducing a structured IpcError enum with diagnostic capabilities through the miette crate. The changes replace generic error messages with specific error variants that provide actionable help text to users when IPC communication fails.
Changes:
- Added
IpcErrorenum with 7 variants covering connection failures, timeouts, unexpected responses, and I/O errors - Replaced
bail!macro calls with structured error types that include diagnostic codes and helpful suggestions - Enhanced serialization/deserialization error messages with format context (JSON vs MessagePack)
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/error.rs | Defines the new IpcError enum with diagnostic attributes and includes unit tests for error display formatting |
| src/ipc/client.rs | Replaces bail! calls with IpcError variants throughout IPC client operations and adds a helper method for unexpected response errors |
| src/ipc/mod.rs | Adds format context to serialization/deserialization errors and improves trace logging for binary data |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/ipc/mod.rs
Outdated
| let format = if *env::IPC_JSON { | ||
| "JSON" | ||
| } else { | ||
| "MessagePack" | ||
| }; | ||
| let msg = if *env::IPC_JSON { |
There was a problem hiding this comment.
The format string is determined twice using identical conditional logic. Consider storing the result of the first check and reusing it, or combine the format determination with the serialization call to reduce duplication.
src/ipc/mod.rs
Outdated
| let format = if *env::IPC_JSON { | ||
| "JSON" | ||
| } else { | ||
| "MessagePack" | ||
| }; | ||
| let msg = if *env::IPC_JSON { |
There was a problem hiding this comment.
The format string is determined twice using identical conditional logic. Consider storing the result of the first check and reusing it, or combine the format determination with the deserialization call to reduce duplication.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
Introduce IpcError enum for better error reporting in IPC operations: - ConnectionFailed: suggests running `pitchfork supervisor start` - Timeout: indicates supervisor may be unresponsive - ConnectionClosed: suggests supervisor may have crashed - ReadFailed/SendFailed: with error details - UnexpectedResponse: shows expected vs actual response - InvalidMessage: for corrupted messages Also improves serialization error context with format info (JSON/MessagePack). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add details field to IpcError::ConnectionFailed to preserve the underlying error (e.g., 'connection refused', 'no such file') - Pass error details when connection attempts are exhausted - Remove duplicate format string logic in serialize/deserialize by inlining the format name directly in each branch Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3f94fc4 to
8f88aa3
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return Err(IpcError::ConnectionFailed { | ||
| attempts: CONNECT_ATTEMPTS, | ||
| details: Some(format!( | ||
| "{err}\nensure the supervisor is running with: pitchfork supervisor start" |
There was a problem hiding this comment.
The help text 'ensure the supervisor is running with: pitchfork supervisor start' is duplicated in the details field here (line 70-71) and in the fallback case (lines 81-82). Consider extracting this message to a constant to maintain consistency.
| let preview = std::str::from_utf8(&bytes).unwrap_or("<binary>"); | ||
| trace!("msg: {:?}", preview); |
There was a problem hiding this comment.
The variable name 'preview' suggests this is a limited view of the data, but the code attempts to convert the entire bytes buffer to UTF-8. Consider renaming to 'message_text' or 'decoded_message' to better reflect that it represents the full decoded content or a fallback label.
| let preview = std::str::from_utf8(&bytes).unwrap_or("<binary>"); | |
| trace!("msg: {:?}", preview); | |
| let decoded_message = std::str::from_utf8(&bytes).unwrap_or("<binary>"); | |
| trace!("msg: {:?}", decoded_message); |
## 🤖 New release * `pitchfork-cli`: 1.1.0 -> 1.2.0 <details><summary><i><b>Changelog</b></i></summary><p> <blockquote> ## [1.2.0](v1.1.0...v1.2.0) - 2026-01-19 ### Added - enhance miette error diagnostics with source highlighting and URLs ([#183](#183)) - add structured IPC error types with miette diagnostics ([#181](#181)) - add structured config error types with file path context ([#182](#182)) - add config editor to TUI for creating and editing daemons ([#171](#171)) - add custom diagnostic error types with miette ([#180](#180)) ### Other - improve miette error handling adoption ([#177](#177)) - modularize supervisor.rs into focused submodules ([#175](#175)) </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/release-plz/release-plz/). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Release 1.2.0** > > - Bump version to `1.2.0` in `Cargo.toml`, `Cargo.lock`, `docs/cli/commands.json`, `docs/cli/index.md`, and `pitchfork.usage.kdl` > - Regenerate CLI docs/usage specs to reflect the new version > - Update `CHANGELOG.md` with highlights: enhanced `miette` diagnostics (source highlighting, URLs), structured IPC/config error types, custom diagnostic errors, TUI config editor; plus adoption improvements and supervisor modularization > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 32b3259. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Summary
IpcErrorenum with structured error variants for IPC operationsbail!calls with diagnostic error types that include helpful suggestionsError Types Added
ConnectionFailedTimeoutConnectionClosedUnexpectedResponseReadFailed/SendFailedInvalidMessageExample Output
Test plan
🤖 Generated with Claude Code
Note
Introduces structured, diagnosable IPC errors and propagates them through the IPC client, improving user-facing diagnostics and reliability.
IpcErrorvariants (ConnectionFailed,Timeout,ConnectionClosed,ReadFailed,SendFailed,UnexpectedResponse,InvalidMessage) insrc/error.rswith miette codes/helpsrc/ipc/client.rsto replacebail!/ensurewithIpcError, addunexpected_responsehelper, map timeouts/IO errors/null-byte messages to specific variants, and surface connect retry failures with detailssrc/ipc/mod.rsserialization/deserialization to attach context for JSON/MessagePack and log a safe message previewIpcErrordisplay formattingWritten by Cursor Bugbot for commit 8f88aa3. This will update automatically on new commits. Configure here.