使用 tonic::Status 和 redis::RedisError 的 Redis 和 Tonic 异步应用程序的正确错误处理
Proper Error handling for a Redis and Tonic async application with tonic::Status and redis::RedisError
我正在制作一个使用 Redis 客户端的基于 Tonic 的 gRPC 微服务。我想不出在发生异步错误时将 RedisError
隐式转换为 tonic::Status
的示例。
async fn make_transaction(
&self,
request: Request<TransactionRequest>,
) -> Result<Response<TransactionResponse>, Status> {
let mut con = self.client.get_async_connection().await?;
con.set("my_key", 42).await?;
来自Redis 客户端的连接可能会像设置一样失败。我正在使用使用 Tokio 的异步接口。我宁愿不 map
错误,因为这似乎会破坏异步。
我在想我需要实现特征 From<Status>
和 From<RedisError
但不确定如何去做。这是我的尝试,但它不起作用,因为 Tonic 想要一个 tonic::Status
结构而不是我制作的 ApiError
结构:
pub struct ApiError {
}
impl From<tonic::Status> for ApiError {
fn from(err: Status) -> ApiError {
ApiError { }
}
}
impl From<RedisError> for Status {
fn from(err: redis::RedisError) -> ApiError {
ApiError { }
}
}
我今天遇到了类似的问题。我设法通过使用自定义类型作为原始错误(在您的情况下是 RedisError)的过渡容器来解决它,因此类似以下的内容也可能对您有用:
pub struct ApiError {}
impl From<RedisError> for ApiError {
fn from(err: redis::RedisError) -> Self {
Self { }
}
}
impl From<ApiError> for Status {
fn from(err: ApiError) -> Self {
Self::internal("Failed talking to Redis")
}
}
async fn set_key(client: ..., key: &str, value: i64) -> Result<(), ApiError> {
let mut con = client.get_async_connection().await?;
con.set(key, value).await?
}
async fn make_transaction(
&self,
request: Request<TransactionRequest>,
) -> Result<Response<TransactionResponse>, Status> {
set_key(self.client, "my_key".into(), 42).await?
}
但我是 Rust 菜鸟,所以我不确定这是否是最好的方法...
我正在制作一个使用 Redis 客户端的基于 Tonic 的 gRPC 微服务。我想不出在发生异步错误时将 RedisError
隐式转换为 tonic::Status
的示例。
async fn make_transaction(
&self,
request: Request<TransactionRequest>,
) -> Result<Response<TransactionResponse>, Status> {
let mut con = self.client.get_async_connection().await?;
con.set("my_key", 42).await?;
来自Redis 客户端的连接可能会像设置一样失败。我正在使用使用 Tokio 的异步接口。我宁愿不 map
错误,因为这似乎会破坏异步。
我在想我需要实现特征 From<Status>
和 From<RedisError
但不确定如何去做。这是我的尝试,但它不起作用,因为 Tonic 想要一个 tonic::Status
结构而不是我制作的 ApiError
结构:
pub struct ApiError {
}
impl From<tonic::Status> for ApiError {
fn from(err: Status) -> ApiError {
ApiError { }
}
}
impl From<RedisError> for Status {
fn from(err: redis::RedisError) -> ApiError {
ApiError { }
}
}
我今天遇到了类似的问题。我设法通过使用自定义类型作为原始错误(在您的情况下是 RedisError)的过渡容器来解决它,因此类似以下的内容也可能对您有用:
pub struct ApiError {}
impl From<RedisError> for ApiError {
fn from(err: redis::RedisError) -> Self {
Self { }
}
}
impl From<ApiError> for Status {
fn from(err: ApiError) -> Self {
Self::internal("Failed talking to Redis")
}
}
async fn set_key(client: ..., key: &str, value: i64) -> Result<(), ApiError> {
let mut con = client.get_async_connection().await?;
con.set(key, value).await?
}
async fn make_transaction(
&self,
request: Request<TransactionRequest>,
) -> Result<Response<TransactionResponse>, Status> {
set_key(self.client, "my_key".into(), 42).await?
}
但我是 Rust 菜鸟,所以我不确定这是否是最好的方法...