Skip to content

Commit e92e3a6

Browse files
committed
Introduce DbPoolError to store Redis and timeout errors
1 parent d940ed2 commit e92e3a6

File tree

3 files changed

+56
-14
lines changed

3 files changed

+56
-14
lines changed

payjoin-directory/src/db.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::time::Duration;
33
use futures::StreamExt;
44
use redis::{AsyncCommands, Client, ErrorKind, RedisError, RedisResult};
55
use tracing::debug;
6+
use crate::error::DbPoolError;
67

78
const DEFAULT_COLUMN: &str = "";
89
const PJ_V1_COLUMN: &str = "pjv1";
@@ -19,19 +20,24 @@ impl DbPool {
1920
Ok(Self { client, timeout })
2021
}
2122

23+
/// Peek using [`DEFAULT_COLUMN`] as the channel type.
2224
pub async fn push_default(&self, subdirectory_id: &str, data: Vec<u8>) -> RedisResult<()> {
2325
self.push(subdirectory_id, DEFAULT_COLUMN, data).await
2426
}
2527

26-
pub async fn peek_default(&self, subdirectory_id: &str) -> Option<RedisResult<Vec<u8>>> {
28+
pub async fn peek_default(
29+
&self,
30+
subdirectory_id: &str,
31+
) -> Result<Vec<u8>, DbPoolError> {
2732
self.peek_with_timeout(subdirectory_id, DEFAULT_COLUMN).await
2833
}
2934

3035
pub async fn push_v1(&self, subdirectory_id: &str, data: Vec<u8>) -> RedisResult<()> {
3136
self.push(subdirectory_id, PJ_V1_COLUMN, data).await
3237
}
3338

34-
pub async fn peek_v1(&self, subdirectory_id: &str) -> Option<RedisResult<Vec<u8>>> {
39+
/// Peek using [`PJ_V1_COLUMN`] as the channel type.
40+
pub async fn peek_v1(&self, subdirectory_id: &str) -> Result<Vec<u8>, DbPoolError> {
3541
self.peek_with_timeout(subdirectory_id, PJ_V1_COLUMN).await
3642
}
3743

@@ -52,8 +58,16 @@ impl DbPool {
5258
&self,
5359
subdirectory_id: &str,
5460
channel_type: &str,
55-
) -> Option<RedisResult<Vec<u8>>> {
56-
tokio::time::timeout(self.timeout, self.peek(subdirectory_id, channel_type)).await.ok()
61+
) -> Result<Vec<u8>, DbPoolError> {
62+
match tokio::time::timeout(self.timeout, self.peek(subdirectory_id, channel_type)).await {
63+
Ok(redis_result) => {
64+
match redis_result {
65+
Ok(result) => { Ok(result) }
66+
Err(redis_err) => { Err(DbPoolError::Redis(redis_err))}
67+
}
68+
}
69+
Err(elapsed) => {Err(DbPoolError::Timeout(elapsed))}
70+
}
5771
}
5872

5973
async fn peek(&self, subdirectory_id: &str, channel_type: &str) -> RedisResult<Vec<u8>> {

payjoin-directory/src/error.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#[derive(Debug)]
2+
pub enum DbPoolError {
3+
Redis(redis::RedisError),
4+
Timeout(tokio::time::error::Elapsed)
5+
}
6+
7+
impl std::fmt::Display for DbPoolError {
8+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9+
use DbPoolError::*;
10+
11+
match &self {
12+
Redis(error) => write!(f, "Redis error: {}", error),
13+
Timeout(timeout) => write!(f, "Timeout: {}", timeout)
14+
}
15+
}
16+
}
17+
18+
impl std::error::Error for DbPoolError {
19+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
20+
match self {
21+
DbPoolError::Redis(e) => Some(e),
22+
DbPoolError::Timeout(e) => Some(e),
23+
}
24+
}
25+
}

payjoin-directory/src/lib.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ const V1_UNAVAILABLE_RES_JSON: &str = r#"{{"errorCode": "unavailable", "message"
3434
const ID_LENGTH: usize = 13;
3535

3636
mod db;
37+
mod error;
38+
3739
use crate::db::DbPool;
40+
use crate::error::DbPoolError;
3841

3942
#[cfg(feature = "_danger-local-https")]
4043
type BoxError = Box<dyn std::error::Error + Send + Sync>;
@@ -341,11 +344,11 @@ async fn post_fallback_v1(
341344
.await
342345
.map_err(|e| HandlerError::BadRequest(e.into()))?;
343346
match pool.peek_v1(id).await {
344-
Some(result) => match result {
345-
Ok(buffered_req) => Ok(Response::new(full(buffered_req))),
346-
Err(e) => Err(HandlerError::BadRequest(e.into())),
347-
},
348-
None => Ok(none_response),
347+
Ok(buffered_req) => Ok(Response::new(full(buffered_req))),
348+
Err(e) => match e {
349+
DbPoolError::Redis(_) => Err(HandlerError::BadRequest(e.into())),
350+
DbPoolError::Timeout(_) => Ok(none_response)
351+
}
349352
}
350353
}
351354

@@ -409,11 +412,11 @@ async fn get_subdir(
409412
trace!("get_subdir");
410413
let id = check_id_length(id)?;
411414
match pool.peek_default(id).await {
412-
Some(result) => match result {
413-
Ok(buffered_req) => Ok(Response::new(full(buffered_req))),
414-
Err(e) => Err(HandlerError::BadRequest(e.into())),
415-
},
416-
None => Ok(Response::builder().status(StatusCode::ACCEPTED).body(empty())?),
415+
Ok(buffered_req) => Ok(Response::new(full(buffered_req))),
416+
Err(e) => match e {
417+
DbPoolError::Redis(_) => Err(HandlerError::BadRequest(e.into())),
418+
DbPoolError::Timeout(_) => Ok(Response::builder().status(StatusCode::ACCEPTED).body(empty())?),
419+
}
417420
}
418421
}
419422

0 commit comments

Comments
 (0)