Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 24 additions & 20 deletions api/blocking.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ let blocking = client.blocking();
Block a contact. Accepts either a LID or a PN JID; the client resolves the LID↔PN pair from its mapping cache and emits a stanza carrying both (`jid=LID`, `pn_jid=PN`). Modern WhatsApp servers reject PN-only block requests.

```rust
pub async fn block(&self, jid: &Jid) -> Result<(), IqError>
pub async fn block(&self, jid: &Jid) -> Result<(), BlockingError>
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
```

**Parameters:**
- `jid` - Contact JID to block (LID or PN)

**Requirements:**
- A LID↔PN mapping for the target must exist in the client's mapping store. If no mapping is available, the call returns `IqError::EncodeError`.
- A LID↔PN mapping for the target must exist in the client's mapping store. If no mapping is available, the call returns `BlockingError::InvalidJid`.

**Effects:**
- Contact will not be able to message you
Expand All @@ -46,7 +46,7 @@ println!("Blocked {}", contact);
Unblock a previously blocked contact. Accepts either a LID or a PN JID; PN input is internally resolved to the LID required on the wire.

```rust
pub async fn unblock(&self, jid: &Jid) -> Result<(), IqError>
pub async fn unblock(&self, jid: &Jid) -> Result<(), BlockingError>
```

**Parameters:**
Expand All @@ -64,7 +64,7 @@ println!("Unblocked {}", contact);
Retrieve the full list of blocked contacts.

```rust
pub async fn get_blocklist(&self) -> Result<Vec<BlocklistEntry>, anyhow::Error>
pub async fn get_blocklist(&self) -> Result<Vec<BlocklistEntry>, BlockingError>
```

**Returns:**
Expand Down Expand Up @@ -94,7 +94,7 @@ for entry in blocklist {
Check if a specific contact is blocked. Accepts either a LID or a PN JID; the client resolves the LID↔PN pair from its mapping cache so a PN-input query correctly matches a LID-keyed blocklist entry (and vice versa).

```rust
pub async fn is_blocked(&self, jid: &Jid) -> Result<bool, anyhow::Error>
pub async fn is_blocked(&self, jid: &Jid) -> Result<bool, BlockingError>
```

**Parameters:**
Expand Down Expand Up @@ -136,22 +136,26 @@ The timestamp may be `None` if the server doesn't provide it.

## Error Types

### IqError
### `BlockingError`

Returned by `block()` and `unblock()` operations:
All methods return `Result<T, BlockingError>`:

```rust
pub enum IqError {
// Network/protocol errors
Timeout,
InvalidResponse,
// ... other variants
#[non_exhaustive]
pub enum BlockingError {
#[error(transparent)]
Iq(#[from] IqError),
#[error("invalid blocklist target: {0}")]
InvalidJid(String),
#[error(transparent)]
Internal(#[from] anyhow::Error),
}
```

### anyhow::Error

Returned by `get_blocklist()` and `is_blocked()` for general errors.
**Variants:**
- `Iq` — Wraps an IQ request failure (timeout, server error, etc.)
- `InvalidJid` — The provided JID was not a valid blocklist target
- `Internal` — Internal error (network, encoding, etc.)

## Wire Format

Expand Down Expand Up @@ -297,17 +301,17 @@ for contact in contacts_to_block {
## Error Handling

```rust
use whatsapp_rust::request::IqError;
use whatsapp_rust::BlockingError;

let contact: Jid = "15551234567@s.whatsapp.net".parse()?;

match client.blocking().block(&contact).await {
Ok(_) => println!("Blocked successfully"),
Err(IqError::Timeout) => {
eprintln!("Request timed out");
Err(BlockingError::Iq(e)) => {
eprintln!("IQ request failed: {}", e);
}
Err(IqError::InvalidResponse) => {
eprintln!("Invalid response from server");
Err(BlockingError::InvalidJid(msg)) => {
eprintln!("Invalid JID: {}", msg);
}
Err(e) => eprintln!("Error: {}", e),
}
Expand Down
8 changes: 4 additions & 4 deletions api/bot.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ Extracts a `MessageContext` from an `Event`. Returns `None` if the event is not
### send_message

```rust
pub async fn send_message(&self, message: wa::Message) -> Result<SendResult, anyhow::Error>
pub async fn send_message(&self, message: wa::Message) -> Result<SendResult, SendError>
```

Sends a message to the same chat. Returns a [`SendResult`](/api/send#sendresult) containing the `message_id` and `to` JID.
Expand Down Expand Up @@ -711,7 +711,7 @@ pub async fn edit_message(
&self,
original_message_id: impl Into<String>,
new_message: wa::Message
) -> Result<String, anyhow::Error>
) -> Result<String, SendError>
```

Edits a message in the same chat.
Expand All @@ -723,15 +723,15 @@ pub async fn revoke_message(
&self,
message_id: String,
revoke_type: RevokeType
) -> Result<(), anyhow::Error>
) -> Result<(), SendError>
```

Deletes a message in the same chat.

### react

```rust
pub async fn react(&self, emoji: &str) -> Result<SendResult, anyhow::Error>
pub async fn react(&self, emoji: &str) -> Result<SendResult, SendError>
```

Sends an emoji reaction to the incoming message. The chat JID, target message ID, and group/status `participant` are taken from the context — you only supply the emoji. Pass an empty string (`""`) to remove a previously sent reaction.
Expand Down
57 changes: 35 additions & 22 deletions api/chat-actions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub async fn archive_chat(
&self,
jid: &Jid,
message_range: Option<SyncActionMessageRange>,
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand All @@ -46,7 +46,7 @@ pub async fn unarchive_chat(
&self,
jid: &Jid,
message_range: Option<SyncActionMessageRange>,
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand All @@ -65,7 +65,7 @@ client.chat_actions().unarchive_chat(&jid, None).await?;
Pin a chat to keep it at the top of the chat list.

```rust
pub async fn pin_chat(&self, jid: &Jid) -> Result<()>
pub async fn pin_chat(&self, jid: &Jid) -> Result<(), AppStateError>
```

**Parameters:**
Expand All @@ -86,7 +86,7 @@ WhatsApp limits the number of pinned chats. Attempting to pin too many chats may
Unpin a chat.

```rust
pub async fn unpin_chat(&self, jid: &Jid) -> Result<()>
pub async fn unpin_chat(&self, jid: &Jid) -> Result<(), AppStateError>
```

**Parameters:**
Expand All @@ -104,7 +104,7 @@ client.chat_actions().unpin_chat(&jid).await?;
Mute a chat indefinitely.

```rust
pub async fn mute_chat(&self, jid: &Jid) -> Result<()>
pub async fn mute_chat(&self, jid: &Jid) -> Result<(), AppStateError>
```

**Parameters:**
Expand All @@ -125,7 +125,7 @@ pub async fn mute_chat_until(
&self,
jid: &Jid,
mute_end_timestamp_ms: i64
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand Down Expand Up @@ -156,7 +156,7 @@ client.chat_actions()
Unmute a chat.

```rust
pub async fn unmute_chat(&self, jid: &Jid) -> Result<()>
pub async fn unmute_chat(&self, jid: &Jid) -> Result<(), AppStateError>
```

**Parameters:**
Expand All @@ -180,7 +180,7 @@ pub async fn star_message(
participant_jid: Option<&Jid>,
message_id: &str,
from_me: bool
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand Down Expand Up @@ -223,7 +223,7 @@ pub async fn unstar_message(
participant_jid: Option<&Jid>,
message_id: &str,
from_me: bool
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand All @@ -248,7 +248,7 @@ pub async fn mark_chat_as_read(
jid: &Jid,
read: bool,
message_range: Option<SyncActionMessageRange>,
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand Down Expand Up @@ -283,7 +283,7 @@ pub async fn delete_chat(
jid: &Jid,
delete_media: bool,
message_range: Option<SyncActionMessageRange>,
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand Down Expand Up @@ -319,7 +319,7 @@ pub async fn clear_chat(
delete_starred: bool,
delete_media: bool,
message_range: Option<SyncActionMessageRange>,
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand Down Expand Up @@ -356,7 +356,7 @@ pub async fn save_contact(
full_name: Option<String>,
first_name: Option<String>,
save_on_primary_addressbook: bool,
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand Down Expand Up @@ -385,7 +385,7 @@ pub async fn set_user_status_mute(
&self,
jid: &Jid,
muted: bool,
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand Down Expand Up @@ -417,7 +417,7 @@ pub async fn delete_message_for_me(
from_me: bool,
delete_media: bool,
message_timestamp: Option<i64>,
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand Down Expand Up @@ -489,7 +489,7 @@ pub async fn send_app_state_action(
schema: &Schema,
index_args: &[&str],
value: &wa::SyncActionValue,
) -> Result<()>
) -> Result<(), AppStateError>
```

**Parameters:**
Expand Down Expand Up @@ -592,17 +592,30 @@ use wacore::types::events::Event;

## Error handling

All methods return `Result<(), anyhow::Error>`. Common errors:
All methods return `Result<(), AppStateError>`:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Update chat-action signatures to AppStateError

This section now says all chat actions return AppStateError, and the #893 implementation does (Result<(), AppStateError>), but every signature on this page still shows bare Result<()> (e.g. archive_chat, pin_chat, mute_chat_until). Callers copying the API reference won't know the actual error type to import or match; update the method signatures as part of this typed-error migration.

Useful? React with 👍 / 👎.


- No app state sync key available (sync not complete)
- Invalid timestamp for `mute_chat_until`
- Missing `participant_jid` for group star/delete operations
- Network errors
```rust
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum AppStateError {
#[error("invalid app-state request: {0}")]
InvalidRequest(String),
#[error(transparent)]
Internal(#[from] anyhow::Error),
}
```

You'll encounter these most often:
- `InvalidRequest` — you passed an invalid timestamp to `mute_chat_until` or omitted `participant_jid` for a group operation
- `Internal` — no app state sync key is available yet (sync not complete), or a network error occurred

```rust
use whatsapp_rust::AppStateError;

match client.chat_actions().mute_chat_until(&jid, 0).await {
Ok(_) => println!("Muted"),
Err(e) => eprintln!("Failed: {}", e), // Timestamp validation error
Err(AppStateError::InvalidRequest(msg)) => eprintln!("Validation error: {}", msg),
Err(e) => eprintln!("Failed: {}", e),
}
```

Expand Down
24 changes: 12 additions & 12 deletions api/chatstate.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ pub async fn send(
&self,
to: &Jid,
state: ChatStateType,
) -> Result<(), ClientError>
) -> Result<(), ChatStateError>
```

**Parameters:**
- `to` - Recipient JID (user or group)
- `state: ChatStateType` - Type of chat state to send

**Returns:**
- `Result<(), ClientError>` - Success or client error
- `Result<(), ChatStateError>` — `Ok(())` on success; a `ChatStateError` if the client is disconnected or the JID is invalid

Comment thread
coderabbitai[bot] marked this conversation as resolved.
**Example:**
```rust
Expand All @@ -55,7 +55,7 @@ client.chatstate().send(&recipient, ChatStateType::Paused).await?;
Convenience method to send typing indicator.

```rust
pub async fn send_composing(&self, to: &Jid) -> Result<(), ClientError>
pub async fn send_composing(&self, to: &Jid) -> Result<(), ChatStateError>
```

**Example:**
Expand All @@ -69,7 +69,7 @@ client.chatstate().send_composing(&recipient).await?;
Convenience method to send audio recording indicator.

```rust
pub async fn send_recording(&self, to: &Jid) -> Result<(), ClientError>
pub async fn send_recording(&self, to: &Jid) -> Result<(), ChatStateError>
```

**Example:**
Expand All @@ -84,7 +84,7 @@ println!("Showing 'recording audio' indicator");
Convenience method to send paused/stopped typing indicator.

```rust
pub async fn send_paused(&self, to: &Jid) -> Result<(), ClientError>
pub async fn send_paused(&self, to: &Jid) -> Result<(), ChatStateError>
```

**Example:**
Expand Down Expand Up @@ -349,21 +349,21 @@ client.send_message(group_jid.clone(), message).await?;

## Error Handling

All methods return `Result<(), ClientError>`. Common errors:
All methods return `Result<(), ChatStateError>`. You'll encounter these most often:

- **Not connected**: Client not connected to WhatsApp
- **Invalid JID**: Malformed recipient JID
- **Network errors**: Connection issues
- **Not connected** — you are not connected to WhatsApp
- **Invalid JID** — the recipient JID is malformed
- **Network errors** — connection dropped mid-send

```rust
use whatsapp_rust::client::ClientError;
use whatsapp_rust::ChatStateError;

let recipient: Jid = "15551234567@s.whatsapp.net".parse()?;

match client.chatstate().send_composing(&recipient).await {
Ok(_) => println!("Sent typing indicator"),
Err(ClientError::NotConnected) => {
eprintln!("Not connected to WhatsApp");
Err(ChatStateError::Client(e)) => {
eprintln!("Client error: {}", e);
}
Err(e) => eprintln!("Error: {}", e),
}
Expand Down
Loading