handle errors within System methods

This commit is contained in:
Aravinth Manivannan 2021-08-20 18:35:22 +05:30
parent ec5a38093c
commit b2684d9348
Signed by: realaravinth
GPG Key ID: AD9F0F08E855ED88
5 changed files with 33 additions and 27 deletions

View File

@ -22,6 +22,9 @@
`crate::master::embedded::master`, it automatically starts `Counter` `crate::master::embedded::master`, it automatically starts `Counter`
actor. actor.
- `System::get_pow` returns `errors::CaptchaResult<Option<PoWConfig>>`
instead of `Option<PoWConfig>`
## 0.1.3 ## 0.1.3
## Added ## Added

View File

@ -90,7 +90,7 @@ async fn main() -> std::io::Result<()> {
// Get PoW config. Should be called everytime there's a visitor for a // Get PoW config. Should be called everytime there's a visitor for a
// managed site(here mcaptcha_name) // managed site(here mcaptcha_name)
let work_req = system.get_pow(mcaptcha_name.into()).await.unwrap(); let work_req = system.get_pow(mcaptcha_name.into()).await.unwrap().unwrap();
// the following computation should be done on the client but for the purpose // the following computation should be done on the client but for the purpose
// of this illustration, we are going to do it on the server it self // of this illustration, we are going to do it on the server it self

View File

@ -20,6 +20,8 @@
use derive_more::{Display, Error}; use derive_more::{Display, Error};
#[cfg(feature = "full")] #[cfg(feature = "full")]
use redis::RedisError; use redis::RedisError;
#[cfg(feature = "full")]
use tokio::sync::oneshot::error::RecvError;
/// Error datatype /// Error datatype
#[derive(Debug, PartialEq, Display, Error)] #[derive(Debug, PartialEq, Display, Error)]
@ -88,6 +90,11 @@ pub enum CaptchaError {
#[cfg(feature = "full")] #[cfg(feature = "full")]
RedisError(RedisError), RedisError(RedisError),
/// Channel receive error
#[display(fmt = "{}", _0)]
#[cfg(feature = "full")]
RecvError(RecvError),
/// Weird behaviour from mcaptcha redis module /// Weird behaviour from mcaptcha redis module
#[display( #[display(
fmt = "Something weird happening with mCaptcha redis module. Please file bug report" fmt = "Something weird happening with mCaptcha redis module. Please file bug report"
@ -121,6 +128,15 @@ impl From<RedisError> for CaptchaError {
} }
} }
#[cfg(feature = "full")]
#[cfg(not(tarpaulin_include))]
impl From<RecvError> for CaptchaError {
fn from(e: RecvError) -> Self {
log::error!("{:?}", e);
Self::RecvError(e)
}
}
#[cfg(feature = "full")] #[cfg(feature = "full")]
#[cfg(not(tarpaulin_include))] #[cfg(not(tarpaulin_include))]
impl From<actix::MailboxError> for CaptchaError { impl From<actix::MailboxError> for CaptchaError {

View File

@ -138,7 +138,7 @@
//! //!
//! // Get PoW config. Should be called everytime there's a visitor for a //! // Get PoW config. Should be called everytime there's a visitor for a
//! // managed site(here mcaptcha_name) //! // managed site(here mcaptcha_name)
//! let work_req = system.get_pow(mcaptcha_name.into()).await.unwrap(); //! let work_req = system.get_pow(mcaptcha_name.into()).await.unwrap().unwrap();
//! //!
//! // the following computation should be done on the client but for the purpose //! // the following computation should be done on the client but for the purpose
//! // of this illustration, we are going to do it on the server it self //! // of this illustration, we are going to do it on the server it self

View File

@ -85,15 +85,8 @@ where
<X as actix::Actor>::Context: ToEnvelope<X, AddVisitor> + ToEnvelope<X, AddSite>, <X as actix::Actor>::Context: ToEnvelope<X, AddVisitor> + ToEnvelope<X, AddSite>,
{ {
/// utility function to get difficulty factor of site `id` and cache it /// utility function to get difficulty factor of site `id` and cache it
pub async fn get_pow(&self, id: String) -> Option<PoWConfig> { pub async fn get_pow(&self, id: String) -> CaptchaResult<Option<PoWConfig>> {
match self match self.master.send(AddVisitor(id.clone())).await?.await? {
.master
.send(AddVisitor(id.clone()))
.await
.unwrap()
.await
.unwrap()
{
Ok(Some(mcaptcha)) => { Ok(Some(mcaptcha)) => {
let pow_config = PoWConfig::new(mcaptcha.difficulty_factor, self.pow.salt.clone()); let pow_config = PoWConfig::new(mcaptcha.difficulty_factor, self.pow.salt.clone());
@ -105,16 +98,10 @@ where
.build() .build()
.unwrap(); .unwrap();
self.cache self.cache.send(cache_msg).await?.await??;
.send(cache_msg) Ok(Some(pow_config))
.await
.unwrap()
.await
.unwrap()
.unwrap();
Some(pow_config)
} }
_ => None, _ => Ok(None),
} }
} }
@ -127,7 +114,7 @@ where
}; };
let msg = RetrivePoW(msg); let msg = RetrivePoW(msg);
let cached_config = self.cache.send(msg).await.unwrap().await.unwrap()?; let cached_config = self.cache.send(msg).await?.await??;
if cached_config.is_none() { if cached_config.is_none() {
return Err(CaptchaError::StringNotFound); return Err(CaptchaError::StringNotFound);
@ -154,7 +141,7 @@ where
let msg: CacheResult = cached_config.into(); let msg: CacheResult = cached_config.into();
let res = msg.token.clone(); let res = msg.token.clone();
self.cache.send(msg).await.unwrap().await.unwrap()?; self.cache.send(msg).await?.await??;
Ok(res) Ok(res)
} }
@ -163,7 +150,7 @@ where
&self, &self,
msg: VerifyCaptchaResult, msg: VerifyCaptchaResult,
) -> CaptchaResult<bool> { ) -> CaptchaResult<bool> {
self.cache.send(msg).await.unwrap().await.unwrap() self.cache.send(msg).await?.await?
} }
} }
@ -211,7 +198,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn get_pow_works() { async fn get_pow_works() {
let actors = boostrap_system(10).await; let actors = boostrap_system(10).await;
let pow = actors.get_pow(MCAPTCHA_NAME.into()).await.unwrap(); let pow = actors.get_pow(MCAPTCHA_NAME.into()).await.unwrap().unwrap();
assert_eq!(pow.difficulty_factor, LEVEL_1.0); assert_eq!(pow.difficulty_factor, LEVEL_1.0);
} }
@ -220,7 +207,7 @@ mod tests {
// start system // start system
let actors = boostrap_system(10).await; let actors = boostrap_system(10).await;
// get work // get work
let work_req = actors.get_pow(MCAPTCHA_NAME.into()).await.unwrap(); let work_req = actors.get_pow(MCAPTCHA_NAME.into()).await.unwrap().unwrap();
// get config // get config
let config = get_config(); let config = get_config();
@ -261,7 +248,7 @@ mod tests {
let res = actors.verify_pow(payload.clone()).await; let res = actors.verify_pow(payload.clone()).await;
assert_eq!(res, Err(CaptchaError::StringNotFound)); assert_eq!(res, Err(CaptchaError::StringNotFound));
let insufficient_work_req = actors.get_pow(MCAPTCHA_NAME.into()).await.unwrap(); let insufficient_work_req = actors.get_pow(MCAPTCHA_NAME.into()).await.unwrap().unwrap();
let insufficient_work = config.prove_work(&insufficient_work_req.string, 1).unwrap(); let insufficient_work = config.prove_work(&insufficient_work_req.string, 1).unwrap();
let insufficient_work_payload = Work { let insufficient_work_payload = Work {
string: insufficient_work_req.string, string: insufficient_work_req.string,
@ -272,7 +259,7 @@ mod tests {
let res = actors.verify_pow(insufficient_work_payload.clone()).await; let res = actors.verify_pow(insufficient_work_payload.clone()).await;
assert_eq!(res, Err(CaptchaError::InsuffiencientDifficulty)); assert_eq!(res, Err(CaptchaError::InsuffiencientDifficulty));
let sitekeyfail_config = actors.get_pow(MCAPTCHA_NAME.into()).await.unwrap(); let sitekeyfail_config = actors.get_pow(MCAPTCHA_NAME.into()).await.unwrap().unwrap();
let sitekeyfail_work = config let sitekeyfail_work = config
.prove_work( .prove_work(
&sitekeyfail_config.string, &sitekeyfail_config.string,