Skip to content

Commit

Permalink
Remove trait implementation to convert anyhow Error to SdkError
Browse files Browse the repository at this point in the history
  • Loading branch information
dangeross committed Oct 9, 2023
1 parent c354667 commit 0f6b4fb
Show file tree
Hide file tree
Showing 25 changed files with 366 additions and 238 deletions.
4 changes: 2 additions & 2 deletions libs/sdk-bindings/src/breez_sdk.udl
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ dictionary RouteHintHop {
enum ServiceErrorCode {
"BackupFailed",
"ClientError",
"CryptographicError",
"DerivationFailed",
"Generic",
"InitFailed",
"NotReady",
"PersistenceFailed",
"RequestFailed",
"ShutdownFailed",
"SignatureError",
"StreamAlreadyCreated",
"TransportError",
};
Expand Down Expand Up @@ -55,7 +55,7 @@ enum OnchainErrorCode {

enum ValueErrorCode {
"ConversionFailed",
"DecodingFailed",
"InvalidInvoice",
"InvalidMnemonic",
"InvalidSignature",
"InvalidTimestamp",
Expand Down
5 changes: 2 additions & 3 deletions libs/sdk-bindings/src/uniffi_binding.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::sync::Arc;

use anyhow::{anyhow, Result};
use log::{Level, LevelFilter, Metadata, Record};
use once_cell::sync::{Lazy, OnceCell};

Expand Down Expand Up @@ -95,10 +94,10 @@ pub fn connect(
}

/// If used, this must be called before `connect`
pub fn set_log_stream(log_stream: Box<dyn LogStream>) -> Result<()> {
pub fn set_log_stream(log_stream: Box<dyn LogStream>) -> SdkResult<()> {
LOG_INIT
.set(true)
.map_err(|_| anyhow!("log stream already created"))?;
.map_err(|_| SdkError::init_failed("log stream already created"))?;
BindingLogger::init(log_stream);
Ok(())
}
Expand Down
41 changes: 28 additions & 13 deletions libs/sdk-core/src/breez_services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use serde_json::json;
use tokio::sync::{mpsc, watch, Mutex};
use tokio::time::sleep;
use tonic::codegen::InterceptedService;
use tonic::metadata::errors::InvalidMetadataValue;
use tonic::metadata::{Ascii, MetadataValue};
use tonic::service::Interceptor;
use tonic::transport::{Channel, Uri};
Expand Down Expand Up @@ -218,7 +219,9 @@ impl BreezServices {
"BreezServices is not running",
));
}
self.shutdown_sender.send(()).map_err(anyhow::Error::msg)?;
self.shutdown_sender.send(()).map_err(|e| {
SdkError::service_error(ServiceErrorCode::ShutdownFailed, &e.to_string())
})?;
*started = false;
Ok(())
}
Expand Down Expand Up @@ -324,7 +327,9 @@ impl BreezServices {
})?;
let preimage_arr: [u8; 32] = preimage.into_inner();

let decrypted = (data, &preimage_arr).try_into()?;
let decrypted = (data, &preimage_arr).try_into().map_err(|e| {
SdkError::generic(&format!("Error decrypting data: {e}"))
})?;
SuccessActionProcessed::Aes { data: decrypted }
}
SuccessAction::Message(data) => {
Expand Down Expand Up @@ -442,7 +447,7 @@ impl BreezServices {
.sign_message(&request.message)
.await
.map(|signature| SignMessageResponse { signature })
.map_err(|e| SdkError::signature_error(&format!("Failed to sign message: {e}")))
.map_err(|e| SdkError::cryptographic_error(&format!("Failed to sign message: {e}")))
}

/// Check whether given message was signed by the private key or the given
Expand All @@ -455,7 +460,7 @@ impl BreezServices {
.check_message(&request.message, &request.pubkey, &request.signature)
.await
.map(|is_valid| CheckMessageResponse { is_valid })
.map_err(|e| SdkError::signature_error(&format!("Failed to check message: {e}")))
.map_err(|e| SdkError::cryptographic_error(&format!("Failed to check message: {e}")))
}

/// Retrieve the node up to date BackupStatus
Expand Down Expand Up @@ -798,7 +803,7 @@ impl BreezServices {
}

/// Connects to the selected LSP, if any
async fn connect_lsp_peer(&self) -> Result<()> {
async fn connect_lsp_peer(&self) -> SdkResult<()> {
if let Ok(lsp_info) = self.lsp_info().await {
let node_id = lsp_info.pubkey;
let address = lsp_info.host;
Expand Down Expand Up @@ -848,12 +853,12 @@ impl BreezServices {
}
}

async fn on_event(&self, e: BreezEvent) -> Result<()> {
async fn on_event(&self, e: BreezEvent) -> SdkResult<()> {
debug!("breez services got event {:?}", e);
self.notify_event_listeners(e.clone()).await
}

async fn notify_event_listeners(&self, e: BreezEvent) -> Result<()> {
async fn notify_event_listeners(&self, e: BreezEvent) -> SdkResult<()> {
if let Err(err) = self.btc_receive_swapper.on_event(e.clone()).await {
debug!(
"btc_receive_swapper failed to process event {:?}: {:?}",
Expand Down Expand Up @@ -935,7 +940,7 @@ impl BreezServices {
/// Starts the BreezServices background threads.
///
/// Internal method. Should only be used as part of [BreezServices::start]
async fn start_background_tasks(self: &Arc<BreezServices>) -> Result<()> {
async fn start_background_tasks(self: &Arc<BreezServices>) -> SdkResult<()> {
// start the signer
let (shutdown_signer_sender, signer_signer_receiver) = mpsc::channel(1);
self.start_signer(signer_signer_receiver).await;
Expand Down Expand Up @@ -1246,8 +1251,11 @@ impl BreezServices {
async fn closed_channel_to_transaction(
&self,
channel: crate::models::Channel,
) -> Result<Payment> {
let now_epoch_sec = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
) -> SdkResult<Payment> {
let now_epoch_sec = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_err(|e| SdkError::generic(&format!("System time error: {e}")))?
.as_secs();

let channel_closed_at = match channel.closed_at {
Some(closed_at) => closed_at,
Expand Down Expand Up @@ -1589,12 +1597,19 @@ impl BreezServer {

pub(crate) async fn get_channel_opener_client(
&self,
) -> Result<ChannelOpenerClient<InterceptedService<Channel, ApiKeyInterceptor>>> {
) -> SdkResult<ChannelOpenerClient<InterceptedService<Channel, ApiKeyInterceptor>>> {
let s = self.server_url.clone();
let channel = Channel::from_shared(s)?.connect().await?;
let channel = Channel::from_shared(s)
.map_err(|e| SdkError::invalid_url(&e.to_string()))?
.connect()
.await?;

let api_key_metadata: Option<MetadataValue<Ascii>> = match &self.api_key {
Some(key) => Some(format!("Bearer {key}").parse()?),
Some(key) => Some(format!("Bearer {key}").parse().map_err(
|e: InvalidMetadataValue| {
SdkError::service_error(ServiceErrorCode::ClientError, &e.to_string())
},
)?),
_ => None,
};
let client =
Expand Down
56 changes: 39 additions & 17 deletions libs/sdk-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub enum ServiceErrorCode {
PersistenceFailed,
RequestFailed,
ShutdownFailed,
SignatureError,
CryptographicError,
StreamAlreadyCreated,
TransportError,
}
Expand Down Expand Up @@ -90,7 +90,7 @@ impl fmt::Display for OnchainErrorCode {
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
pub enum ValueErrorCode {
ConversionFailed,
DecodingFailed,
InvalidInvoice,
InvalidMnemonic,
InvalidSignature,
InvalidTimestamp,
Expand Down Expand Up @@ -142,8 +142,19 @@ impl SdkError {
)
}

pub fn conversion_failed(err: &str) -> Self {
Self::value_error(ValueErrorCode::ConversionFailed, err)
}

pub fn cryptographic_error(err: &str) -> Self {
Self::service_error(ServiceErrorCode::CryptographicError, err)
}

pub fn decoding_failed(err: &str) -> Self {
Self::value_error(ValueErrorCode::DecodingFailed, err)
Self::value_error(
ValueErrorCode::ConversionFailed,
&format!("Decoding failed: {err}"),
)
}

pub fn derive_encryption_key_failed(e: Error) -> Self {
Expand All @@ -153,6 +164,13 @@ impl SdkError {
)
}

pub fn encoding_failed(err: &str) -> Self {
Self::value_error(
ValueErrorCode::ConversionFailed,
&format!("Encoding failed: {err}"),
)
}

pub fn generic(err: &str) -> Self {
Self::service_error(ServiceErrorCode::Generic, err)
}
Expand Down Expand Up @@ -245,10 +263,6 @@ impl SdkError {
}
}

pub fn signature_error(err: &str) -> Self {
Self::service_error(ServiceErrorCode::SignatureError, err)
}

pub fn swap_provider_error(err: &str) -> Self {
Self::onchain_error(OnchainErrorCode::SwapProviderError, err)
}
Expand Down Expand Up @@ -301,6 +315,12 @@ impl From<serde_json::Error> for SdkError {
}
}

impl From<base64::DecodeError> for SdkError {
fn from(value: base64::DecodeError) -> Self {
Self::decoding_failed(&value.to_string())
}
}

impl From<bitcoin::hashes::hex::Error> for SdkError {
fn from(value: bitcoin::hashes::hex::Error) -> Self {
Self::decoding_failed(&value.to_string())
Expand All @@ -315,7 +335,7 @@ impl From<bitcoin::util::address::Error> for SdkError {

impl From<bitcoin::util::sighash::Error> for SdkError {
fn from(value: bitcoin::util::sighash::Error) -> Self {
Self::signature_error(&value.to_string())
Self::cryptographic_error(&value.to_string())
}
}

Expand All @@ -331,15 +351,24 @@ impl From<reqwest::Error> for SdkError {
}
}

impl From<std::num::ParseIntError> for SdkError {
fn from(value: std::num::ParseIntError) -> Self {
Self::value_error(
ValueErrorCode::UnknownValue,
&format!("Parsing error: {value}"),
)
}
}

impl From<secp256k1::Error> for SdkError {
fn from(value: secp256k1::Error) -> Self {
Self::signature_error(&value.to_string())
Self::cryptographic_error(&value.to_string())
}
}

impl From<tonic::transport::Error> for SdkError {
fn from(value: tonic::transport::Error) -> Self {
Self::signature_error(&value.to_string())
Self::service_error(ServiceErrorCode::TransportError, &value.to_string())
}
}

Expand All @@ -349,13 +378,6 @@ impl From<tonic::Status> for SdkError {
}
}

// TODO This won't be necessary when all service methods return SdkResult
impl From<anyhow::Error> for SdkError {
fn from(value: anyhow::Error) -> Self {
Self::generic(&value.to_string())
}
}

#[macro_export]
macro_rules! ensure_sdk {
($cond:expr, $err:expr) => {
Expand Down
1 change: 1 addition & 0 deletions libs/sdk-core/src/greenlight/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub(crate) enum JsonRpcErrCode {
WaitTimeout = 2000,
}

#[allow(clippy::invalid_regex)]
pub(crate) fn parse_cln_error(err: Error) -> Result<Option<JsonRpcErrCode>> {
let re = Regex::new(r"Some\((?<code>-?\d+)\)")?;
re.captures(&err.to_string()).map_or(Ok(None), |caps| {
Expand Down
Loading

0 comments on commit 0f6b4fb

Please sign in to comment.