From 697ac5e9ce781651cf239cea3c31264131b0c13a Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 21 Oct 2023 15:00:50 -0400 Subject: [PATCH] error cleanup --- .../src/routing_table/route_spec_store/mod.rs | 16 ++--- .../tasks/private_route_management.rs | 4 +- veilid-core/src/rpc_processor/destination.rs | 66 ++++++------------- veilid-core/src/rpc_processor/fanout_call.rs | 9 ++- veilid-core/src/rpc_processor/mod.rs | 42 ++++-------- veilid-core/src/rpc_processor/rpc_app_call.rs | 7 +- .../src/rpc_processor/rpc_app_message.rs | 7 +- .../src/rpc_processor/rpc_cancel_tunnel.rs | 5 +- .../src/rpc_processor/rpc_complete_tunnel.rs | 5 +- veilid-core/src/rpc_processor/rpc_error.rs | 21 ++++++ .../src/rpc_processor/rpc_find_block.rs | 5 +- .../src/rpc_processor/rpc_find_node.rs | 7 +- .../src/rpc_processor/rpc_get_value.rs | 4 +- .../src/rpc_processor/rpc_return_receipt.rs | 7 +- veilid-core/src/rpc_processor/rpc_route.rs | 19 +++--- .../src/rpc_processor/rpc_set_value.rs | 4 +- veilid-core/src/rpc_processor/rpc_signal.rs | 7 +- .../src/rpc_processor/rpc_start_tunnel.rs | 5 +- veilid-core/src/rpc_processor/rpc_status.rs | 7 +- .../src/rpc_processor/rpc_supply_block.rs | 5 +- .../rpc_processor/rpc_validate_dial_info.rs | 5 +- .../src/rpc_processor/rpc_value_changed.rs | 5 +- .../src/rpc_processor/rpc_watch_value.rs | 5 +- veilid-core/src/storage_manager/get_value.rs | 39 +++++------ veilid-core/src/storage_manager/mod.rs | 6 +- .../src/storage_manager/record_store.rs | 4 +- veilid-core/src/storage_manager/set_value.rs | 34 +++++----- veilid-core/src/veilid_api/api.rs | 10 +-- veilid-core/src/veilid_api/error.rs | 43 ++++++++---- .../src/veilid_api/json_api/process.rs | 2 +- veilid-core/src/veilid_api/routing_context.rs | 14 ++-- veilid-flutter/lib/veilid_api_exception.dart | 21 ++++-- veilid-python/veilid/error.py | 2 + veilid-tools/src/network_result.rs | 2 +- .../src/tests/native/test_assembly_buffer.rs | 12 ++-- 35 files changed, 205 insertions(+), 251 deletions(-) diff --git a/veilid-core/src/routing_table/route_spec_store/mod.rs b/veilid-core/src/routing_table/route_spec_store/mod.rs index 534eabff..e31d67c7 100644 --- a/veilid-core/src/routing_table/route_spec_store/mod.rs +++ b/veilid-core/src/routing_table/route_spec_store/mod.rs @@ -228,8 +228,9 @@ impl RouteSpecStore { // Ensure we have a valid network class so our peer info is useful if !rti.has_valid_network_class(RoutingDomain::PublicInternet) { - log_rtab!(debug "unable to allocate route until we have a valid PublicInternet network class"); - apibail_try_again!(); + apibail_try_again!( + "unable to allocate route until we have a valid PublicInternet network class" + ); }; // Get our peer info @@ -381,8 +382,7 @@ impl RouteSpecStore { // If we couldn't find enough nodes, wait until we have more nodes in the routing table if nodes.len() < hop_count { - log_rtab!(debug "not enough nodes to construct route at this time"); - apibail_try_again!(); + apibail_try_again!("not enough nodes to construct route at this time"); } // Get peer info for everything @@ -534,8 +534,7 @@ impl RouteSpecStore { } } if route_nodes.is_empty() { - log_rtab!(debug "unable to find unique route at this time"); - apibail_try_again!(); + apibail_try_again!("unable to find unique route at this time"); } drop(perm_func); @@ -1309,8 +1308,9 @@ impl RouteSpecStore { // Ensure our network class is valid before attempting to assemble any routes if !rti.has_valid_network_class(RoutingDomain::PublicInternet) { - log_rtab!(debug "unable to assemble route until we have a valid PublicInternet network class"); - apibail_try_again!(); + apibail_try_again!( + "unable to assemble route until we have a valid PublicInternet network class" + ); } // Make innermost route hop to our own node diff --git a/veilid-core/src/routing_table/tasks/private_route_management.rs b/veilid-core/src/routing_table/tasks/private_route_management.rs index 2f53f19f..e28c3f61 100644 --- a/veilid-core/src/routing_table/tasks/private_route_management.rs +++ b/veilid-core/src/routing_table/tasks/private_route_management.rs @@ -213,7 +213,9 @@ impl RoutingTable { DirectionSet::all(), &[], ) { - Err(VeilidAPIError::TryAgain) => {} + Err(VeilidAPIError::TryAgain { message }) => { + log_rtab!(debug "Route allocation unavailable: {}", message); + } Err(e) => return Err(e.into()), Ok(v) => { newly_allocated_routes.push(v); diff --git a/veilid-core/src/rpc_processor/destination.rs b/veilid-core/src/rpc_processor/destination.rs index d3aff08d..609cd07d 100644 --- a/veilid-core/src/rpc_processor/destination.rs +++ b/veilid-core/src/rpc_processor/destination.rs @@ -164,7 +164,7 @@ impl RPCProcessor { pub(super) fn get_destination_respond_to( &self, dest: &Destination, - ) -> Result, RPCError> { + ) -> RPCNetworkResult { let routing_table = self.routing_table(); let rss = routing_table.route_spec_store(); @@ -180,21 +180,13 @@ impl RPCProcessor { SafetySelection::Safe(safety_spec) => { // Sent directly but with a safety route, respond to private route let crypto_kind = target.best_node_id().kind; - let pr_key = match rss.get_private_route_for_safety_spec( - crypto_kind, - safety_spec, - &target.node_ids(), - ) { - Err(VeilidAPIError::TryAgain) => { - return Ok(NetworkResult::no_connection_other( - "no private route for response at this time", - )); - } - Err(e) => { - return Err(RPCError::internal(e)); - } - Ok(v) => v, - }; + let pr_key = network_result_try!(rss + .get_private_route_for_safety_spec( + crypto_kind, + safety_spec, + &target.node_ids(), + ) + .to_rpc_network_result()?); // Get the assembled route for response let private_route = rss @@ -219,21 +211,9 @@ impl RPCProcessor { let mut avoid_nodes = relay.node_ids(); avoid_nodes.add_all(&target.node_ids()); - let pr_key = match rss.get_private_route_for_safety_spec( - crypto_kind, - safety_spec, - &avoid_nodes, - ) { - Err(VeilidAPIError::TryAgain) => { - return Ok(NetworkResult::no_connection_other( - "no private route for response at this time", - )); - } - Err(e) => { - return Err(RPCError::internal(e)); - } - Ok(v) => v, - }; + let pr_key = network_result_try!(rss + .get_private_route_for_safety_spec(crypto_kind, safety_spec, &avoid_nodes,) + .to_rpc_network_result()?); // Get the assembled route for response let private_route = rss @@ -259,7 +239,7 @@ impl RPCProcessor { SafetySelection::Unsafe(_) => { // Sent to a private route with no safety route, use a stub safety route for the response if !routing_table.has_valid_network_class(RoutingDomain::PublicInternet) { - return Ok(NetworkResult::no_connection_other( + return Ok(NetworkResult::service_unavailable( "Own node info must be valid to use private route", )); } @@ -292,21 +272,13 @@ impl RPCProcessor { private_route.public_key.value } else { // Get the private route to respond to that matches the safety route spec we sent the request with - match rss.get_private_route_for_safety_spec( - crypto_kind, - safety_spec, - &[avoid_node_id], - ) { - Err(VeilidAPIError::TryAgain) => { - return Ok(NetworkResult::no_connection_other( - "no private route for response at this time", - )); - } - Err(e) => { - return Err(RPCError::internal(e)); - } - Ok(v) => v, - } + network_result_try!(rss + .get_private_route_for_safety_spec( + crypto_kind, + safety_spec, + &[avoid_node_id], + ) + .to_rpc_network_result()?) }; // Get the assembled route for response diff --git a/veilid-core/src/rpc_processor/fanout_call.rs b/veilid-core/src/rpc_processor/fanout_call.rs index 3ae25137..1ff4e8d0 100644 --- a/veilid-core/src/rpc_processor/fanout_call.rs +++ b/veilid-core/src/rpc_processor/fanout_call.rs @@ -8,7 +8,7 @@ where result: Option>, } -pub type FanoutCallReturnType = Result>, RPCError>; +pub type FanoutCallReturnType = RPCNetworkResult>; pub type FanoutNodeInfoFilter = Arc bool + Send + Sync>; pub fn empty_fanout_node_info_filter() -> FanoutNodeInfoFilter { @@ -132,7 +132,7 @@ where // Do the call for this node match (self.call_routine)(next_node.clone()).await { - Ok(Some(v)) => { + Ok(NetworkResult::Value(v)) => { // Filter returned nodes let filtered_v: Vec = v .into_iter() @@ -155,8 +155,11 @@ where .register_find_node_answer(self.crypto_kind, filtered_v); self.clone().add_to_fanout_queue(&new_nodes); } - Ok(None) => { + #[allow(unused_variables)] + Ok(x) => { // Call failed, node will not be considered again + #[cfg(feature = "network-result-extra")] + log_rpc!(debug "Fanout result {}: {:?}", &next_node, x); } Err(e) => { // Error happened, abort everything and return the error diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index 2894fe85..19f87b67 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -469,24 +469,15 @@ impl RPCProcessor { let call_routine = |next_node: NodeRef| { let this = self.clone(); async move { - match this + let v = network_result_try!(this .clone() .rpc_call_find_node( Destination::direct(next_node).with_safety(safety_selection), node_id, vec![], ) - .await - { - Ok(v) => { - let v = network_result_value_or_log!(v => [ format!(": node_id={} count={} fanout={} fanout={} safety_selection={:?}", node_id, count, fanout, timeout_us, safety_selection) ] { - // Any other failures, just try the next node - return Ok(None); - }); - Ok(Some(v.answer)) - } - Err(e) => Err(e), - } + .await?); + Ok(NetworkResult::value(v.answer)) } }; @@ -636,7 +627,7 @@ impl RPCProcessor { remote_private_route: PrivateRoute, reply_private_route: Option, message_data: Vec, - ) -> Result, RPCError> { + ) -> RPCNetworkResult { let routing_table = self.routing_table(); let rss = routing_table.route_spec_store(); @@ -650,19 +641,8 @@ impl RPCProcessor { }; // Compile the safety route with the private route - let compiled_route: CompiledRoute = match rss - .compile_safety_route(safety_selection, remote_private_route) - { - Err(VeilidAPIError::TryAgain) => { - return Ok(NetworkResult::no_connection_other( - "private route could not be compiled at this time", - )) - } - Err(e) => { - return Err(RPCError::internal(e)); - } - Ok(v) => v, - }; + let compiled_route: CompiledRoute = network_result_try!(rss + .compile_safety_route(safety_selection, remote_private_route).to_rpc_network_result()?); let sr_is_stub = compiled_route.safety_route.is_stub(); let sr_pubkey = compiled_route.safety_route.public_key.value; @@ -723,7 +703,7 @@ impl RPCProcessor { &self, dest: Destination, operation: &RPCOperation, - ) -> Result, RPCError> { + ) ->RPCNetworkResult { let out: NetworkResult; // Encode message to a builder and make a message reader for it @@ -1162,7 +1142,7 @@ impl RPCProcessor { dest: Destination, question: RPCQuestion, context: Option, - ) -> Result, RPCError> { + ) ->RPCNetworkResult { // Get sender peer info if we should send that let spi = self.get_sender_peer_info(&dest); @@ -1258,7 +1238,7 @@ impl RPCProcessor { &self, dest: Destination, statement: RPCStatement, - ) -> Result, RPCError> { + ) ->RPCNetworkResult<()> { // Get sender peer info if we should send that let spi = self.get_sender_peer_info(&dest); @@ -1333,7 +1313,7 @@ impl RPCProcessor { &self, request: RPCMessage, answer: RPCAnswer, - ) -> Result, RPCError> { + ) ->RPCNetworkResult<()> { // Extract destination from respond_to let dest = network_result_try!(self.get_respond_to_destination(&request)); @@ -1459,7 +1439,7 @@ impl RPCProcessor { async fn process_rpc_message( &self, encoded_msg: RPCMessageEncoded, - ) -> Result, RPCError> { + ) ->RPCNetworkResult<()> { let address_filter = self.network_manager.address_filter(); // Decode operation appropriately based on header detail diff --git a/veilid-core/src/rpc_processor/rpc_app_call.rs b/veilid-core/src/rpc_processor/rpc_app_call.rs index 37c21deb..239768ca 100644 --- a/veilid-core/src/rpc_processor/rpc_app_call.rs +++ b/veilid-core/src/rpc_processor/rpc_app_call.rs @@ -11,7 +11,7 @@ impl RPCProcessor { self, dest: Destination, message: Vec, - ) -> Result>>, RPCError> { + ) -> RPCNetworkResult>> { let debug_string = format!("AppCall(message(len)={}) => {}", message.len(), dest); let app_call_q = RPCOperationAppCallQ::new(message)?; @@ -49,10 +49,7 @@ impl RPCProcessor { } #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_app_call_q( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_app_call_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled let routing_table = self.routing_table(); diff --git a/veilid-core/src/rpc_processor/rpc_app_message.rs b/veilid-core/src/rpc_processor/rpc_app_message.rs index 9f6a3d89..d0aac195 100644 --- a/veilid-core/src/rpc_processor/rpc_app_message.rs +++ b/veilid-core/src/rpc_processor/rpc_app_message.rs @@ -11,7 +11,7 @@ impl RPCProcessor { self, dest: Destination, message: Vec, - ) -> Result, RPCError> { + ) -> RPCNetworkResult<()> { let app_message = RPCOperationAppMessage::new(message)?; let statement = RPCStatement::new(RPCStatementDetail::AppMessage(Box::new(app_message))); @@ -20,10 +20,7 @@ impl RPCProcessor { } #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_app_message( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_app_message(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled let routing_table = self.routing_table(); let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); diff --git a/veilid-core/src/rpc_processor/rpc_cancel_tunnel.rs b/veilid-core/src/rpc_processor/rpc_cancel_tunnel.rs index 2e761488..133ded54 100644 --- a/veilid-core/src/rpc_processor/rpc_cancel_tunnel.rs +++ b/veilid-core/src/rpc_processor/rpc_cancel_tunnel.rs @@ -2,10 +2,7 @@ use super::*; impl RPCProcessor { #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_cancel_tunnel_q( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_cancel_tunnel_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled #[cfg(feature = "unstable-tunnels")] { diff --git a/veilid-core/src/rpc_processor/rpc_complete_tunnel.rs b/veilid-core/src/rpc_processor/rpc_complete_tunnel.rs index c13088c1..4b97985f 100644 --- a/veilid-core/src/rpc_processor/rpc_complete_tunnel.rs +++ b/veilid-core/src/rpc_processor/rpc_complete_tunnel.rs @@ -2,10 +2,7 @@ use super::*; impl RPCProcessor { #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_complete_tunnel_q( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_complete_tunnel_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled #[cfg(feature = "unstable-tunnels")] { diff --git a/veilid-core/src/rpc_processor/rpc_error.rs b/veilid-core/src/rpc_processor/rpc_error.rs index f20f7102..dc339fb7 100644 --- a/veilid-core/src/rpc_processor/rpc_error.rs +++ b/veilid-core/src/rpc_processor/rpc_error.rs @@ -13,6 +13,8 @@ pub enum RPCError { Internal(String), #[error("[RPCError: Network({0})]")] Network(String), + #[error("[RPCError: TryAgain({0})]")] + TryAgain(String), } impl RPCError { @@ -56,6 +58,25 @@ impl From for VeilidAPIError { RPCError::Protocol(message) => VeilidAPIError::Generic { message }, RPCError::Internal(message) => VeilidAPIError::Internal { message }, RPCError::Network(message) => VeilidAPIError::Generic { message }, + RPCError::TryAgain(message) => VeilidAPIError::TryAgain { message }, + } + } +} + +pub(crate) type RPCNetworkResult = Result, RPCError>; + +pub(crate) trait ToRPCNetworkResult { + fn to_rpc_network_result(self) -> RPCNetworkResult; +} + +impl ToRPCNetworkResult for VeilidAPIResult { + fn to_rpc_network_result(self) -> RPCNetworkResult { + match self { + Err(VeilidAPIError::TryAgain { message }) => Err(RPCError::TryAgain(message)), + Err(VeilidAPIError::Timeout) => Ok(NetworkResult::timeout()), + Err(VeilidAPIError::Unimplemented { message }) => Err(RPCError::Unimplemented(message)), + Err(e) => Err(RPCError::internal(e)), + Ok(v) => Ok(NetworkResult::value(v)), } } } diff --git a/veilid-core/src/rpc_processor/rpc_find_block.rs b/veilid-core/src/rpc_processor/rpc_find_block.rs index 600f7d83..786cef37 100644 --- a/veilid-core/src/rpc_processor/rpc_find_block.rs +++ b/veilid-core/src/rpc_processor/rpc_find_block.rs @@ -2,10 +2,7 @@ use super::*; impl RPCProcessor { #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_find_block_q( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_find_block_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled #[cfg(feature = "unstable-blockstore")] { diff --git a/veilid-core/src/rpc_processor/rpc_find_node.rs b/veilid-core/src/rpc_processor/rpc_find_node.rs index 088b38b9..ded13285 100644 --- a/veilid-core/src/rpc_processor/rpc_find_node.rs +++ b/veilid-core/src/rpc_processor/rpc_find_node.rs @@ -16,7 +16,7 @@ impl RPCProcessor { dest: Destination, node_id: TypedKey, capabilities: Vec, - ) -> Result>>, RPCError> { + ) -> RPCNetworkResult>> { // Ensure destination never has a private route if matches!( dest, @@ -78,10 +78,7 @@ impl RPCProcessor { } #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_find_node_q( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_find_node_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ensure this never came over a private route, safety route is okay though match &msg.header.detail { RPCMessageHeaderDetail::Direct(_) | RPCMessageHeaderDetail::SafetyRouted(_) => {} diff --git a/veilid-core/src/rpc_processor/rpc_get_value.rs b/veilid-core/src/rpc_processor/rpc_get_value.rs index 89c1aeff..055aaa45 100644 --- a/veilid-core/src/rpc_processor/rpc_get_value.rs +++ b/veilid-core/src/rpc_processor/rpc_get_value.rs @@ -32,7 +32,7 @@ impl RPCProcessor { key: TypedKey, subkey: ValueSubkey, last_descriptor: Option, - ) -> Result>, RPCError> { + ) ->RPCNetworkResult> { // Ensure destination never has a private route // and get the target noderef so we can validate the response let Some(target) = dest.target() else { @@ -168,7 +168,7 @@ impl RPCProcessor { pub(crate) async fn process_get_value_q( &self, msg: RPCMessage, - ) -> Result, RPCError> { + ) ->RPCNetworkResult<()> { // Ensure this never came over a private route, safety route is okay though match &msg.header.detail { diff --git a/veilid-core/src/rpc_processor/rpc_return_receipt.rs b/veilid-core/src/rpc_processor/rpc_return_receipt.rs index 60c13cb2..8d3caaa1 100644 --- a/veilid-core/src/rpc_processor/rpc_return_receipt.rs +++ b/veilid-core/src/rpc_processor/rpc_return_receipt.rs @@ -11,7 +11,7 @@ impl RPCProcessor { self, dest: Destination, receipt: D, - ) -> Result, RPCError> { + ) -> RPCNetworkResult<()> { let receipt = receipt.as_ref().to_vec(); let return_receipt = RPCOperationReturnReceipt::new(receipt)?; @@ -25,10 +25,7 @@ impl RPCProcessor { } #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_return_receipt( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_return_receipt(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Get the statement let (_, _, _, kind) = msg.operation.destructure(); let receipt = match kind { diff --git a/veilid-core/src/rpc_processor/rpc_route.rs b/veilid-core/src/rpc_processor/rpc_route.rs index 117a26a3..d33b9055 100644 --- a/veilid-core/src/rpc_processor/rpc_route.rs +++ b/veilid-core/src/rpc_processor/rpc_route.rs @@ -10,7 +10,7 @@ impl RPCProcessor { routed_operation: RoutedOperation, route_hop: RouteHop, safety_route: SafetyRoute, - ) -> Result, RPCError> { + ) -> RPCNetworkResult<()> { // Make sure hop count makes sense if safety_route.hop_count as usize > self.unlocked_inner.max_route_hop_count { return Ok(NetworkResult::invalid_message( @@ -69,7 +69,7 @@ impl RPCProcessor { next_route_node: RouteNode, safety_route_public_key: TypedKey, next_private_route: PrivateRoute, - ) -> Result, RPCError> { + ) -> RPCNetworkResult<()> { // Make sure hop count makes sense if next_private_route.hop_count as usize > self.unlocked_inner.max_route_hop_count { return Ok(NetworkResult::invalid_message( @@ -122,7 +122,7 @@ impl RPCProcessor { vcrypto: CryptoSystemVersion, routed_operation: RoutedOperation, remote_sr_pubkey: TypedKey, - ) -> Result, RPCError> { + ) -> RPCNetworkResult<()> { // Now that things are valid, decrypt the routed operation with DEC(nonce, DH(the SR's public key, the PR's (or node's) secret) // xxx: punish nodes that send messages that fail to decrypt eventually? How to do this for safety routes? let node_id_secret = self.routing_table.node_id_secret_key(remote_sr_pubkey.kind); @@ -170,7 +170,7 @@ impl RPCProcessor { routed_operation: RoutedOperation, remote_sr_pubkey: TypedKey, pr_pubkey: TypedKey, - ) -> Result, RPCError> { + ) -> RPCNetworkResult<()> { // Get sender id of the peer with the crypto kind of the route let Some(sender_id) = detail.peer_noderef.node_ids().get(pr_pubkey.kind) else { return Ok(NetworkResult::invalid_message( @@ -246,7 +246,7 @@ impl RPCProcessor { routed_operation: RoutedOperation, remote_sr_pubkey: TypedKey, pr_pubkey: TypedKey, - ) -> Result, RPCError> { + ) -> RPCNetworkResult<()> { // If the private route public key is our node id, then this was sent via safety route to our node directly // so there will be no signatures to validate if self.routing_table.node_ids().contains(&pr_pubkey) { @@ -277,7 +277,7 @@ impl RPCProcessor { mut routed_operation: RoutedOperation, sr_pubkey: TypedKey, mut private_route: PrivateRoute, - ) -> Result, RPCError> { + ) -> RPCNetworkResult<()> { let Some(pr_first_hop) = private_route.pop_first_hop() else { return Ok(NetworkResult::invalid_message( "switching from safety route to private route requires first hop", @@ -341,7 +341,7 @@ impl RPCProcessor { route_hop_data: &RouteHopData, pr_pubkey: &TypedKey, route_operation: &mut RoutedOperation, - ) -> Result, RPCError> { + ) -> RPCNetworkResult { // Get crypto kind let crypto_kind = pr_pubkey.kind; let Some(vcrypto) = self.crypto.get(crypto_kind) else { @@ -402,10 +402,7 @@ impl RPCProcessor { feature = "verbose-tracing", instrument(level = "trace", skip(self), ret, err) )] - pub(crate) async fn process_route( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_route(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled let routing_table = self.routing_table(); if !routing_table.has_valid_network_class(msg.header.routing_domain()) { diff --git a/veilid-core/src/rpc_processor/rpc_set_value.rs b/veilid-core/src/rpc_processor/rpc_set_value.rs index b69a8ff5..b507b73e 100644 --- a/veilid-core/src/rpc_processor/rpc_set_value.rs +++ b/veilid-core/src/rpc_processor/rpc_set_value.rs @@ -36,7 +36,7 @@ impl RPCProcessor { value: SignedValueData, descriptor: SignedValueDescriptor, send_descriptor: bool, - ) -> Result>, RPCError> { + ) ->RPCNetworkResult> { // Ensure destination never has a private route // and get the target noderef so we can validate the response let Some(target) = dest.target() else { @@ -182,7 +182,7 @@ impl RPCProcessor { pub(crate) async fn process_set_value_q( &self, msg: RPCMessage, - ) -> Result, RPCError> { + ) ->RPCNetworkResult<()> { // Ignore if disabled let routing_table = self.routing_table(); let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); diff --git a/veilid-core/src/rpc_processor/rpc_signal.rs b/veilid-core/src/rpc_processor/rpc_signal.rs index df041188..056770ee 100644 --- a/veilid-core/src/rpc_processor/rpc_signal.rs +++ b/veilid-core/src/rpc_processor/rpc_signal.rs @@ -11,7 +11,7 @@ impl RPCProcessor { self, dest: Destination, signal_info: SignalInfo, - ) -> Result, RPCError> { + ) -> RPCNetworkResult<()> { // Ensure destination never has a private route if matches!( dest, @@ -33,10 +33,7 @@ impl RPCProcessor { } #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_signal( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_signal(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled let routing_table = self.routing_table(); let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); diff --git a/veilid-core/src/rpc_processor/rpc_start_tunnel.rs b/veilid-core/src/rpc_processor/rpc_start_tunnel.rs index 972ba67b..f6d8b3c7 100644 --- a/veilid-core/src/rpc_processor/rpc_start_tunnel.rs +++ b/veilid-core/src/rpc_processor/rpc_start_tunnel.rs @@ -2,10 +2,7 @@ use super::*; impl RPCProcessor { #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_start_tunnel_q( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_start_tunnel_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled #[cfg(feature = "unstable-tunnels")] { diff --git a/veilid-core/src/rpc_processor/rpc_status.rs b/veilid-core/src/rpc_processor/rpc_status.rs index 0160cced..7c894544 100644 --- a/veilid-core/src/rpc_processor/rpc_status.rs +++ b/veilid-core/src/rpc_processor/rpc_status.rs @@ -22,7 +22,7 @@ impl RPCProcessor { pub async fn rpc_call_status( self, dest: Destination, - ) -> Result>>, RPCError> { + ) -> RPCNetworkResult>> { let (opt_target_nr, routing_domain, node_status) = match dest.get_safety_selection() { SafetySelection::Unsafe(_) => { let (opt_target_nr, routing_domain) = match &dest { @@ -197,10 +197,7 @@ impl RPCProcessor { } #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_status_q( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_status_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Get the question let kind = msg.operation.kind().clone(); let status_q = match kind { diff --git a/veilid-core/src/rpc_processor/rpc_supply_block.rs b/veilid-core/src/rpc_processor/rpc_supply_block.rs index 630635eb..368bd44b 100644 --- a/veilid-core/src/rpc_processor/rpc_supply_block.rs +++ b/veilid-core/src/rpc_processor/rpc_supply_block.rs @@ -2,10 +2,7 @@ use super::*; impl RPCProcessor { #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_supply_block_q( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_supply_block_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled #[cfg(feature = "unstable-blockstore")] { diff --git a/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs b/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs index 2a97d88a..db5e8ef2 100644 --- a/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs +++ b/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs @@ -56,10 +56,7 @@ impl RPCProcessor { } #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_validate_dial_info( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_validate_dial_info(&self, msg: RPCMessage) -> RPCNetworkResult<()> { let routing_table = self.routing_table(); if !routing_table.has_valid_network_class(msg.header.routing_domain()) { return Ok(NetworkResult::service_unavailable( diff --git a/veilid-core/src/rpc_processor/rpc_value_changed.rs b/veilid-core/src/rpc_processor/rpc_value_changed.rs index 0776ce31..96c1b1fc 100644 --- a/veilid-core/src/rpc_processor/rpc_value_changed.rs +++ b/veilid-core/src/rpc_processor/rpc_value_changed.rs @@ -2,10 +2,7 @@ use super::*; impl RPCProcessor { #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), err))] - pub(crate) async fn process_value_changed( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_value_changed(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled let routing_table = self.routing_table(); let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 42095087..7ec9d69a 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -2,10 +2,7 @@ use super::*; impl RPCProcessor { #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] - pub(crate) async fn process_watch_value_q( - &self, - msg: RPCMessage, - ) -> Result, RPCError> { + pub(crate) async fn process_watch_value_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled let routing_table = self.routing_table(); let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); diff --git a/veilid-core/src/storage_manager/get_value.rs b/veilid-core/src/storage_manager/get_value.rs index 85a28a10..3fcb4b0c 100644 --- a/veilid-core/src/storage_manager/get_value.rs +++ b/veilid-core/src/storage_manager/get_value.rs @@ -54,19 +54,17 @@ impl StorageManager { let context = context.clone(); let last_descriptor = last_subkey_result.descriptor.clone(); async move { - let vres = rpc_processor - .clone() - .rpc_call_get_value( - Destination::direct(next_node.clone()).with_safety(safety_selection), - key, - subkey, - last_descriptor, - ) - .await?; - let gva = network_result_value_or_log!(vres => [ format!(": next_node={} safety_selection={:?} key={} subkey={}", next_node, safety_selection, key, subkey) ] { - // Any other failures, just try the next node - return Ok(None); - }); + let gva = network_result_try!( + rpc_processor + .clone() + .rpc_call_get_value( + Destination::direct(next_node.clone()).with_safety(safety_selection), + key, + subkey, + last_descriptor, + ) + .await? + ); // Keep the descriptor if we got one. If we had a last_descriptor it will // already be validated by rpc_call_get_value @@ -87,8 +85,9 @@ impl StorageManager { let (Some(descriptor), Some(schema)) = (&ctx.descriptor, &ctx.schema) else { // Got a value but no descriptor for it // Move to the next node - log_stor!(debug "Got value with no descriptor"); - return Ok(None); + return Ok(NetworkResult::invalid_message( + "Got value with no descriptor", + )); }; // Validate with schema @@ -99,8 +98,10 @@ impl StorageManager { ) { // Validation failed, ignore this value // Move to the next node - log_stor!(debug "Schema validation failed on subkey {}", subkey); - return Ok(None); + return Ok(NetworkResult::invalid_message(format!( + "Schema validation failed on subkey {}", + subkey + ))); } // If we have a prior value, see if this is a newer sequence number @@ -112,7 +113,7 @@ impl StorageManager { // If sequence number is the same, the data should be the same if prior_value.value_data() != value.value_data() { // Move to the next node - return Ok(None); + return Ok(NetworkResult::invalid_message("value data mismatch")); } // Increase the consensus count for the existing value ctx.value_count += 1; @@ -136,7 +137,7 @@ impl StorageManager { #[cfg(feature = "network-result-extra")] log_stor!(debug "GetValue fanout call returned peers {}", gva.answer.peers.len()); - Ok(Some(gva.answer.peers)) + Ok(NetworkResult::value(gva.answer.peers)) } }; diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index 0b28b71b..a04ec1ba 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -209,8 +209,7 @@ impl StorageManager { // Get rpc processor and drop mutex so we don't block while getting the value from the network let Some(rpc_processor) = inner.rpc_processor.clone() else { - // Offline, try again later - apibail_try_again!(); + apibail_try_again!("offline, try again later"); }; // Drop the mutex so we dont block during network access @@ -310,8 +309,7 @@ impl StorageManager { // Get rpc processor and drop mutex so we don't block while getting the value from the network let Some(rpc_processor) = inner.rpc_processor.clone() else { - // Offline, try again later - apibail_try_again!(); + apibail_try_again!("offline, try again later"); }; // Drop the lock for network access diff --git a/veilid-core/src/storage_manager/record_store.rs b/veilid-core/src/storage_manager/record_store.rs index 401d855d..c7a9da80 100644 --- a/veilid-core/src/storage_manager/record_store.rs +++ b/veilid-core/src/storage_manager/record_store.rs @@ -337,7 +337,7 @@ where .unwrap(); if !self.total_storage_space.check_limit() { self.total_storage_space.rollback(); - apibail_try_again!(); + apibail_try_again!("out of storage space"); } // Save to record table @@ -650,7 +650,7 @@ where .add(new_subkey_size as u64) .unwrap(); if !self.total_storage_space.check_limit() { - apibail_try_again!(); + apibail_try_again!("out of storage space"); } // Write subkey diff --git a/veilid-core/src/storage_manager/set_value.rs b/veilid-core/src/storage_manager/set_value.rs index 5c812f24..e7742fac 100644 --- a/veilid-core/src/storage_manager/set_value.rs +++ b/veilid-core/src/storage_manager/set_value.rs @@ -60,21 +60,19 @@ impl StorageManager { }; // send across the wire - let vres = rpc_processor - .clone() - .rpc_call_set_value( - Destination::direct(next_node.clone()).with_safety(safety_selection), - key, - subkey, - value, - descriptor.clone(), - send_descriptor, - ) - .await?; - let sva = network_result_value_or_log!(vres => [ format!(": next_node={} safety_selection={:?} key={} subkey={} send_descriptor={}", next_node, safety_selection, key, subkey, send_descriptor) ] { - // Any other failures, just try the next node and pretend this one never happened - return Ok(None); - }); + let sva = network_result_try!( + rpc_processor + .clone() + .rpc_call_set_value( + Destination::direct(next_node.clone()).with_safety(safety_selection), + key, + subkey, + value, + descriptor.clone(), + send_descriptor, + ) + .await? + ); // If the node was close enough to possibly set the value if sva.answer.set { @@ -91,7 +89,7 @@ impl StorageManager { value.value_data(), ) { // Validation failed, ignore this value and pretend we never saw this node - return Ok(None); + return Ok(NetworkResult::invalid_message("Schema validation failed")); } // We have a prior value, ensure this is a newer sequence number @@ -107,7 +105,7 @@ impl StorageManager { // If the sequence number is older, or an equal sequence number, // node should have not returned a value here. // Skip this node and its closer list because it is misbehaving - return Ok(None); + return Ok(NetworkResult::invalid_message("Sequence number is older")); } } else { // It was set on this node and no newer value was found and returned, @@ -124,7 +122,7 @@ impl StorageManager { #[cfg(feature = "network-result-extra")] log_stor!(debug "SetValue fanout call returned peers {}", sva.answer.peers.len()); - Ok(Some(sva.answer.peers)) + Ok(NetworkResult::value(sva.answer.peers)) } }; diff --git a/veilid-core/src/veilid_api/api.rs b/veilid-core/src/veilid_api/api.rs index 847e93d5..496dcf66 100644 --- a/veilid-core/src/veilid_api/api.rs +++ b/veilid-core/src/veilid_api/api.rs @@ -200,9 +200,11 @@ impl VeilidAPI { /// `VLD0:XmnGyJrjMJBRC5ayJZRPXWTBspdX36-pbLb98H3UMeE` but if the prefix is left off /// `XmnGyJrjMJBRC5ayJZRPXWTBspdX36-pbLb98H3UMeE` will be parsed with the 'best' cryptosystem /// available (at the time of this writing this is `VLD0`) - pub async fn parse_as_target>(&self, s: S) -> VeilidAPIResult { + pub async fn parse_as_target(&self, s: S) -> VeilidAPIResult { + let s = s.to_string(); + // Is this a route id? - if let Ok(rrid) = RouteId::from_str(s.as_ref()) { + if let Ok(rrid) = RouteId::from_str(&s) { let routing_table = self.routing_table()?; let rss = routing_table.route_spec_store(); @@ -213,11 +215,11 @@ impl VeilidAPI { } // Is this a node id? - if let Ok(nid) = TypedKey::from_str(s.as_ref()) { + if let Ok(nid) = TypedKey::from_str(&s) { return Ok(Target::NodeId(nid)); } - Err(VeilidAPIError::invalid_target()) + Err(VeilidAPIError::parse_error("Unable to parse as target", s)) } //////////////////////////////////////////////////////////////// diff --git a/veilid-core/src/veilid_api/error.rs b/veilid-core/src/veilid_api/error.rs index 39261179..b7c801ea 100644 --- a/veilid-core/src/veilid_api/error.rs +++ b/veilid-core/src/veilid_api/error.rs @@ -19,8 +19,8 @@ macro_rules! apibail_timeout { #[allow(unused_macros)] #[macro_export] macro_rules! apibail_try_again { - () => { - return Err(VeilidAPIError::try_again()) + ($x:expr) => { + return Err(VeilidAPIError::try_again($x)) }; } @@ -83,8 +83,8 @@ macro_rules! apibail_key_not_found { #[allow(unused_macros)] #[macro_export] macro_rules! apibail_invalid_target { - () => { - return Err(VeilidAPIError::invalid_target()) + ($x:expr) => { + return Err(VeilidAPIError::invalid_target($x)) }; } @@ -116,12 +116,12 @@ pub enum VeilidAPIError { AlreadyInitialized, #[error("Timeout")] Timeout, - #[error("TryAgain")] - TryAgain, + #[error("TryAgain: {message}")] + TryAgain { message: String }, #[error("Shutdown")] Shutdown, - #[error("Invalid target")] - InvalidTarget, + #[error("Invalid target: {message}")] + InvalidTarget { message: String }, #[error("No connection: {message}")] NoConnection { message: String }, #[error("Key not found: {key}")] @@ -158,14 +158,18 @@ impl VeilidAPIError { pub fn timeout() -> Self { Self::Timeout } - pub fn try_again() -> Self { - Self::TryAgain + pub fn try_again(msg: T) -> Self { + Self::TryAgain { + message: msg.to_string(), + } } pub fn shutdown() -> Self { Self::Shutdown } - pub fn invalid_target() -> Self { - Self::InvalidTarget + pub fn invalid_target(msg: T) -> Self { + Self::InvalidTarget { + message: msg.to_string(), + } } pub fn no_connection(msg: T) -> Self { Self::NoConnection { @@ -213,6 +217,21 @@ impl VeilidAPIError { message: msg.to_string(), } } + + pub(crate) fn from_network_result(nr: NetworkResult) -> Result { + match nr { + NetworkResult::Timeout => Err(VeilidAPIError::timeout()), + NetworkResult::ServiceUnavailable(m) => Err(VeilidAPIError::invalid_target(m)), + NetworkResult::NoConnection(m) => Err(VeilidAPIError::no_connection(m)), + NetworkResult::AlreadyExists(m) => { + Err(VeilidAPIError::generic(format!("Already exists: {}", m))) + } + NetworkResult::InvalidMessage(m) => { + Err(VeilidAPIError::parse_error("Invalid message", m)) + } + NetworkResult::Value(v) => Ok(v), + } + } } pub type VeilidAPIResult = Result; diff --git a/veilid-core/src/veilid_api/json_api/process.rs b/veilid-core/src/veilid_api/json_api/process.rs index a84be568..e4665d9c 100644 --- a/veilid-core/src/veilid_api/json_api/process.rs +++ b/veilid-core/src/veilid_api/json_api/process.rs @@ -220,7 +220,7 @@ impl JsonRequestProcessor { return Ok(Target::NodeId(nid)); } - Err(VeilidAPIError::invalid_target()) + Err(VeilidAPIError::parse_error("Unable to parse as target", s)) } ////////////////////////////////////////////////////////////////////////////////////// diff --git a/veilid-core/src/veilid_api/routing_context.rs b/veilid-core/src/veilid_api/routing_context.rs index 6e7a9a49..3d7f16a1 100644 --- a/veilid-core/src/veilid_api/routing_context.rs +++ b/veilid-core/src/veilid_api/routing_context.rs @@ -126,7 +126,7 @@ impl RoutingContext { .await { Ok(Some(nr)) => nr, - Ok(None) => apibail_invalid_target!(), + Ok(None) => apibail_invalid_target!("could not resolve node id"), Err(e) => return Err(e.into()), }; // Apply sequencing to match safety selection @@ -142,7 +142,7 @@ impl RoutingContext { let rss = self.api.routing_table()?.route_spec_store(); let Some(private_route) = rss.best_remote_private_route(&rsid) else { - apibail_invalid_target!(); + apibail_invalid_target!("could not get remote private route"); }; Ok(rpc_processor::Destination::PrivateRoute { @@ -174,10 +174,7 @@ impl RoutingContext { let answer = match rpc_processor.rpc_call_app_call(dest, message).await { Ok(NetworkResult::Value(v)) => v, Ok(NetworkResult::Timeout) => apibail_timeout!(), - Ok(NetworkResult::ServiceUnavailable(e)) => { - log_network_result!(format!("app_call: ServiceUnavailable({})", e)); - apibail_try_again!() - } + Ok(NetworkResult::ServiceUnavailable(e)) => apibail_invalid_target!(e), Ok(NetworkResult::NoConnection(e)) | Ok(NetworkResult::AlreadyExists(e)) => { apibail_no_connection!(e); } @@ -207,10 +204,7 @@ impl RoutingContext { match rpc_processor.rpc_call_app_message(dest, message).await { Ok(NetworkResult::Value(())) => {} Ok(NetworkResult::Timeout) => apibail_timeout!(), - Ok(NetworkResult::ServiceUnavailable(e)) => { - log_network_result!(format!("app_message: ServiceUnavailable({})", e)); - apibail_try_again!() - } + Ok(NetworkResult::ServiceUnavailable(e)) => apibail_invalid_target!(e), Ok(NetworkResult::NoConnection(e)) | Ok(NetworkResult::AlreadyExists(e)) => { apibail_no_connection!(e); } diff --git a/veilid-flutter/lib/veilid_api_exception.dart b/veilid-flutter/lib/veilid_api_exception.dart index 433114e9..6eb30393 100644 --- a/veilid-flutter/lib/veilid_api_exception.dart +++ b/veilid-flutter/lib/veilid_api_exception.dart @@ -22,7 +22,7 @@ abstract class VeilidAPIException implements Exception { } case 'TryAgain': { - return VeilidAPIExceptionTryAgain(); + return VeilidAPIExceptionTryAgain(json['message']! as String); } case 'Shutdown': { @@ -30,7 +30,7 @@ abstract class VeilidAPIException implements Exception { } case 'InvalidTarget': { - return VeilidAPIExceptionInvalidTarget(); + return VeilidAPIExceptionInvalidTarget(json['message']! as String); } case 'NoConnection': { @@ -108,11 +108,14 @@ class VeilidAPIExceptionTimeout implements VeilidAPIException { @immutable class VeilidAPIExceptionTryAgain implements VeilidAPIException { + // + const VeilidAPIExceptionTryAgain(this.message); + final String message; @override - String toString() => 'VeilidAPIException: TryAgain'; + String toString() => 'VeilidAPIException: TryAgain (message: $message)'; @override - String toDisplayError() => 'Try again'; + String toDisplayError() => 'Try again: (message: $message)'; } @immutable @@ -126,11 +129,15 @@ class VeilidAPIExceptionShutdown implements VeilidAPIException { @immutable class VeilidAPIExceptionInvalidTarget implements VeilidAPIException { - @override - String toString() => 'VeilidAPIException: InvalidTarget'; + // + const VeilidAPIExceptionInvalidTarget(this.message); + final String message; @override - String toDisplayError() => 'Invalid target'; + String toString() => 'VeilidAPIException: InvalidTarget (message: $message)'; + + @override + String toDisplayError() => 'Invalid target: (message: $message)'; } @immutable diff --git a/veilid-python/veilid/error.py b/veilid-python/veilid/error.py index 17459fcd..73745454 100644 --- a/veilid-python/veilid/error.py +++ b/veilid-python/veilid/error.py @@ -55,6 +55,7 @@ class VeilidAPIErrorTryAgain(VeilidAPIError): """Operation could not be performed at this time, retry again later""" label = "Try again" + message: str @dataclass @@ -69,6 +70,7 @@ class VeilidAPIErrorInvalidTarget(VeilidAPIError): """Target of operation is not valid""" label = "Invalid target" + message: str @dataclass diff --git a/veilid-tools/src/network_result.rs b/veilid-tools/src/network_result.rs index 760cd460..21f6961a 100644 --- a/veilid-tools/src/network_result.rs +++ b/veilid-tools/src/network_result.rs @@ -218,7 +218,7 @@ impl NetworkResult { Self::Value(v) => NetworkResult::::Value(f(v)), } } - pub fn into_result(self) -> Result { + pub fn into_io_result(self) -> Result { match self { Self::Timeout => Err(io::Error::new(io::ErrorKind::TimedOut, "Timed out")), Self::ServiceUnavailable(s) => Err(io::Error::new( diff --git a/veilid-tools/src/tests/native/test_assembly_buffer.rs b/veilid-tools/src/tests/native/test_assembly_buffer.rs index c9fef514..b717a5a8 100644 --- a/veilid-tools/src/tests/native/test_assembly_buffer.rs +++ b/veilid-tools/src/tests/native/test_assembly_buffer.rs @@ -52,7 +52,7 @@ pub async fn test_single_out_in() { // Send to input let r_message = assbuf_in .insert_frame(&frame, r_remote_addr) - .into_result() + .into_io_result() .expect("should get a value") .expect("should get something out"); @@ -114,7 +114,7 @@ pub async fn test_one_frag_out_in() { // Send to input let r_message = assbuf_in .insert_frame(&frame, r_remote_addr) - .into_result() + .into_io_result() .expect("should get a value"); // We should have gotten the same message @@ -179,7 +179,7 @@ pub async fn test_many_frags_out_in() { // Send to input let r_message = assbuf_in .insert_frame(&frame, r_remote_addr) - .into_result() + .into_io_result() .expect("should get a value"); // We should have gotten the same message @@ -244,7 +244,7 @@ pub async fn test_many_frags_out_in_single_host() { // Send to input let r_message = assbuf_in .insert_frame(&frame, r_remote_addr) - .into_result() + .into_io_result() .expect("should get a value"); // We should have gotten the same message @@ -322,7 +322,7 @@ pub async fn test_many_frags_with_drops() { // Send to input let r_message = assbuf_in .insert_frame(&frame, r_remote_addr) - .into_result() + .into_io_result() .expect("should get a value"); // We should have gotten the same message @@ -399,7 +399,7 @@ pub async fn test_many_frags_reordered() { // Send to input let r_message = assbuf_in .insert_frame(&frame, r_remote_addr) - .into_result() + .into_io_result() .expect("should get a value"); // We should have gotten the same message