Skip to content

Commit a020337

Browse files
committed
feat: add support for connected event handling and custom exceptions
1 parent 5d0d014 commit a020337

6 files changed

Lines changed: 125 additions & 4 deletions

File tree

python/tryx/exceptions.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class BuildBotError(Exception):
2+
"""Raised when the bot fails to build properly."""
3+
pass
4+
5+
6+
class FailedToDecodeProtoError(Exception):
7+
"""Raised when the bot fails to decode a protocol buffer."""
8+
pass
9+
10+
11+
class UnsupportedEventTypeError(Exception):
12+
"""Raised when an unsupported event type is encountered."""
13+
pass
14+
15+
16+
class UnsupportedBackendError(Exception):
17+
"""Raised when an unsupported backend is encountered."""
18+
pass

src/client.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ use tracing::{debug, error, info, warn};
2121
use tracing_subscriber::EnvFilter;
2222

2323
use crate::backend::{SqliteBackend, BackendBase};
24-
use crate::events::{Message as WAMessage, PairingQrCode};
24+
use crate::events::{Connected, Message as WAMessage, PairingQrCode};
25+
use crate::exceptions::UnsupportedBackend;
2526
use crate::types::JID;
2627
use crate::dispatcher::Dispatcher;
2728

@@ -192,6 +193,17 @@ impl Tryx {
192193
}
193194
}
194195
}
196+
Event::Connected(_) => {
197+
let callbacks = Python::attach(|py| handlers.clone_ref(py).bind(py).borrow().conneccted_handlers(py));
198+
for (idx, callback) in callbacks.into_iter().enumerate() {
199+
debug!(handler_index = idx, "calling connected event handler");
200+
let _ = Python::attach(|py| -> PyResult<_> {
201+
let awaitable = callback.bind(py).call1((Connected{},))?;
202+
let fut = into_future(awaitable)?;
203+
Ok(fut)
204+
});
205+
}
206+
}
195207
_ => {
196208
debug!("received event without registered dispatcher path");
197209
}
@@ -254,7 +266,7 @@ impl Tryx {
254266
})
255267
} else {
256268
error!("unsupported backend type passed to Tryx");
257-
Err(PyErr::new::<pyo3::exceptions::PyTypeError, _>("Unsupported backend type"))
269+
Err(PyErr::new::<UnsupportedBackend, _>("Unsupported backend type"))
258270
}
259271
}
260272
fn get_client(&self, py: Python<'_>) -> Py<TryxClient> {

src/dispatcher.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use tracing::{debug, info};
33
use pyo3::types::{PyType};
44
use pyo3::{PyTypeInfo};
55
use crate::events::{Connected, Disconnected, LoggedOut, PairSuccess, PairError, PairingCode, PairingQrCode, QrScannedWithoutMultidevice, ClientOutDated, Message};
6+
use crate::exceptions::UnsupportedEventType;
67

78
#[pyclass]
89
pub struct Dispatcher {
@@ -116,6 +117,14 @@ impl Dispatcher {
116117
debug!(handlers = handlers.len(), "collected message handlers");
117118
handlers
118119
}
120+
pub fn conneccted_handlers(&self, py: Python<'_>) -> Vec<Py<PyAny>> {
121+
let handlers = self.connected
122+
.iter()
123+
.map(|handler| handler.clone_ref(py))
124+
.collect::<Vec<_>>();
125+
debug!(handlers = handlers.len(), "collected connected handlers");
126+
handlers
127+
}
119128
fn handlers_for_event(&self, event: DispatchEvent) -> &Vec<Py<PyAny>> {
120129
match event {
121130
DispatchEvent::Connected => &self.connected,
@@ -172,7 +181,8 @@ fn dispatch_event_from_type(py: Python, event_type: &Bound<PyAny>) -> PyResult<D
172181
} else if event_type.is_subclass(&Message::type_object(py))? {
173182
Ok(DispatchEvent::Message)
174183
} else {
175-
Err(pyo3::exceptions::PyValueError::new_err("Unsupported event type"))
184+
Err(PyErr::new::<UnsupportedEventType, _>("Unsupported event type"))
185+
176186
}
177187
}
178188

src/exceptions.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use pyo3::{pyclass, pymethods};
2+
use pyo3::exceptions::PyException;
3+
#[pyclass(extends=PyException)]
4+
pub struct FailedBuildBot {
5+
message: String,
6+
}
7+
8+
#[pymethods]
9+
impl FailedBuildBot {
10+
#[new]
11+
fn new(message: String) -> Self {
12+
FailedBuildBot { message }
13+
}
14+
fn __str__(&self) -> String {
15+
self.message.clone()
16+
}
17+
fn __repr__(&self) -> String {
18+
format!("FailedBuildBot(message='{}')", self.message)
19+
}
20+
}
21+
22+
#[pyclass(extends=PyException)]
23+
struct FailedToDecodeProto {
24+
message: String,
25+
}
26+
27+
#[pymethods]
28+
impl FailedToDecodeProto {
29+
#[new]
30+
fn new(message: String) -> Self {
31+
FailedToDecodeProto { message }
32+
}
33+
fn __str__(&self) -> String {
34+
self.message.clone()
35+
}
36+
fn __repr__(&self) -> String {
37+
format!("FailedToDecodeProto(message='{}')", self.message)
38+
}
39+
}
40+
41+
#[pyclass(extends=PyException)]
42+
pub struct UnsupportedEventType {
43+
pub message: String,
44+
}
45+
46+
#[pymethods]
47+
impl UnsupportedEventType {
48+
#[new]
49+
fn new(message: String) -> Self {
50+
UnsupportedEventType { message }
51+
}
52+
fn __str__(&self) -> String {
53+
self.message.clone()
54+
}
55+
fn __repr__(&self) -> String {
56+
format!("UnsupportedEventType(message='{}')", self.message)
57+
}
58+
}
59+
60+
#[pyclass(extends=PyException)]
61+
pub struct UnsupportedBackend {
62+
message: String,
63+
}
64+
65+
#[pymethods]
66+
impl UnsupportedBackend {
67+
#[new]
68+
fn new(message: String) -> Self {
69+
UnsupportedBackend { message }
70+
}
71+
fn __str__(&self) -> String {
72+
self.message.clone()
73+
}
74+
fn __repr__(&self) -> String {
75+
format!("UnsupportedBackend(message='{}')", self.message)
76+
}
77+
}

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ mod backend;
3131
mod client;
3232
mod events;
3333
mod types;
34-
mod dispatcher;
34+
mod dispatcher;
35+
mod exceptions;

src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
2222
}
2323
Event::Message(msg, info) => {
2424
println!("Message from {}: {:?}", info.source.sender, msg);
25+
}
26+
Event::Connected(e)=> {
27+
println!("Connected to WhatsApp");
2528
}
2629
_ => {}
2730
}

0 commit comments

Comments
 (0)