Skip to content

Commit 61bfaf0

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

File tree

3 files changed

+51
-12
lines changed

3 files changed

+51
-12
lines changed

payjoin-directory/src/db.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use futures::StreamExt;
44
use redis::{AsyncCommands, Client, ErrorKind, RedisError, RedisResult};
55
use tracing::debug;
66

7+
use crate::error::DbPoolError;
8+
79
const DEFAULT_COLUMN: &str = "";
810
const PJ_V1_COLUMN: &str = "pjv1";
911

@@ -19,19 +21,21 @@ impl DbPool {
1921
Ok(Self { client, timeout })
2022
}
2123

24+
/// Peek using [`DEFAULT_COLUMN`] as the channel type.
2225
pub async fn push_default(&self, subdirectory_id: &str, data: Vec<u8>) -> RedisResult<()> {
2326
self.push(subdirectory_id, DEFAULT_COLUMN, data).await
2427
}
2528

26-
pub async fn peek_default(&self, subdirectory_id: &str) -> Option<RedisResult<Vec<u8>>> {
29+
pub async fn peek_default(&self, subdirectory_id: &str) -> Result<Vec<u8>, DbPoolError> {
2730
self.peek_with_timeout(subdirectory_id, DEFAULT_COLUMN).await
2831
}
2932

3033
pub async fn push_v1(&self, subdirectory_id: &str, data: Vec<u8>) -> RedisResult<()> {
3134
self.push(subdirectory_id, PJ_V1_COLUMN, data).await
3235
}
3336

34-
pub async fn peek_v1(&self, subdirectory_id: &str) -> Option<RedisResult<Vec<u8>>> {
37+
/// Peek using [`PJ_V1_COLUMN`] as the channel type.
38+
pub async fn peek_v1(&self, subdirectory_id: &str) -> Result<Vec<u8>, DbPoolError> {
3539
self.peek_with_timeout(subdirectory_id, PJ_V1_COLUMN).await
3640
}
3741

@@ -52,8 +56,14 @@ impl DbPool {
5256
&self,
5357
subdirectory_id: &str,
5458
channel_type: &str,
55-
) -> Option<RedisResult<Vec<u8>>> {
56-
tokio::time::timeout(self.timeout, self.peek(subdirectory_id, channel_type)).await.ok()
59+
) -> Result<Vec<u8>, DbPoolError> {
60+
match tokio::time::timeout(self.timeout, self.peek(subdirectory_id, channel_type)).await {
61+
Ok(redis_result) => match redis_result {
62+
Ok(result) => Ok(result),
63+
Err(redis_err) => Err(DbPoolError::Redis(redis_err)),
64+
},
65+
Err(elapsed) => Err(DbPoolError::Timeout(elapsed)),
66+
}
5767
}
5868

5969
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: 12 additions & 8 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+
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),
347351
},
348-
None => Ok(none_response),
349352
}
350353
}
351354

@@ -409,11 +412,12 @@ 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+
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(_) =>
419+
Ok(Response::builder().status(StatusCode::ACCEPTED).body(empty())?),
415420
},
416-
None => Ok(Response::builder().status(StatusCode::ACCEPTED).body(empty())?),
417421
}
418422
}
419423

0 commit comments

Comments
 (0)