Currently, all client methods return Result<T, LemmyErrorType>. The LemmyErrorType error type is suboptimal for users of the library for multiple reasons:
- it doesn't implement
std::error::Error (although this could be fixed in a one-line PR to lemmy_utils), so it can't be used with eyre/anyhow and anything else that expects an impl Error or dyn Error without wrapping it in another error type
- it doesn't differentiate between HTTP errors and errors that are returned from the lemmy API
- in the case of HTTP errors, the original error isn't preserved (e.g.
reqwest::Error)
Executable Example
#!/usr/bin/env -S cargo +nightly -Zscript
---
package.edition = "2024"
[dependencies]
lemmy-client = "1.0.5"
tokio = { version = "1.45.0", features = ["macros", "rt-multi-thread"] }
---
use lemmy_client::{
ClientOptions, LemmyClient,
lemmy_api_common::{
lemmy_db_schema::newtypes::PostId,
post::{GetPost, GetPosts},
},
};
#[tokio::main]
async fn main() {
http_error().await;
lemmy_error().await;
}
async fn http_error() {
let client = LemmyClient::new(ClientOptions {
domain: "nolemmy.example.org".to_owned(),
secure: true,
});
if let Err(e) = client.list_posts(GetPosts::default()).await {
// Unknown("error sending request for url (https://nolemmy.example.org/api/v3/post/list)")
println!("{e:?}");
}
}
async fn lemmy_error() {
let client = LemmyClient::new(ClientOptions {
domain: "lemm.ee".to_owned(),
secure: true,
});
if let Err(e) = client
.get_post(GetPost {
id: Some(PostId(123456789)),
comment_id: None,
})
.await
{
// CouldntFindPost
println!("{e:?}");
}
}
I suggest that this crate returns a different error type instead that implements std::error::Error, provides access to an underlying error at least via Error::source() and at least provides some methods to check if the error is an HTTP error or an error returned by the API.
This could also be done using the widespread “error enum” pattern (which can be implemented using thiserror, but can also easily be written by hand).
Error Enum Example
#[derive(Debug)]
pub enum Error {
#[cfg(target_family = "wasm")]
Http(gloo::net::Error),
#[cfg(not(target_family = "wasm"))]
Http(reqwest::Error),
Lemmy(LemmyErrorType)
}
P. S.: I think a lot could be implemented easier if this crate used reqwest for both WASM and non-WASM, although I don't know the tradeoffs between gloo::net and reqwest.
Currently, all client methods return
Result<T, LemmyErrorType>. TheLemmyErrorTypeerror type is suboptimal for users of the library for multiple reasons:std::error::Error(although this could be fixed in a one-line PR tolemmy_utils), so it can't be used witheyre/anyhowand anything else that expects animpl Errorordyn Errorwithout wrapping it in another error typereqwest::Error)Executable Example
I suggest that this crate returns a different error type instead that implements
std::error::Error, provides access to an underlying error at least viaError::source()and at least provides some methods to check if the error is an HTTP error or an error returned by the API.This could also be done using the widespread “error enum” pattern (which can be implemented using
thiserror, but can also easily be written by hand).Error Enum Example
P. S.: I think a lot could be implemented easier if this crate used
reqwestfor both WASM and non-WASM, although I don't know the tradeoffs betweengloo::netandreqwest.