diff --git a/linera-rpc/src/grpc/client.rs b/linera-rpc/src/grpc/client.rs index 705614b12a0..3534a79f941 100644 --- a/linera-rpc/src/grpc/client.rs +++ b/linera-rpc/src/grpc/client.rs @@ -73,15 +73,13 @@ impl GrpcClient { info!("gRPC request interrupted: {}; retrying", status); true } - Code::Ok - | Code::Cancelled - | Code::NotFound - | Code::AlreadyExists - | Code::ResourceExhausted => { + Code::Ok | Code::Cancelled | Code::ResourceExhausted => { error!("Unexpected gRPC status: {}; retrying", status); true } Code::InvalidArgument + | Code::NotFound + | Code::AlreadyExists | Code::PermissionDenied | Code::FailedPrecondition | Code::OutOfRange diff --git a/linera-service/Cargo.toml b/linera-service/Cargo.toml index 37af4dce2b3..733a7d28889 100644 --- a/linera-service/Cargo.toml +++ b/linera-service/Cargo.toml @@ -20,7 +20,7 @@ test = [ "linera-execution/test", "dep:stdext", ] -benchmark = ["linera-base/test", "linera-client/benchmark", "dep:linera-sdk"] +benchmark = ["linera-base/test", "linera-client/benchmark"] wasmer = ["linera-client/wasmer", "linera-execution/wasmer", "linera-storage/wasmer"] wasmtime = [ "linera-client/wasmtime", @@ -84,7 +84,7 @@ linera-client = { workspace = true, features = ["fs"] } linera-core.workspace = true linera-execution = { workspace = true, features = ["fs"] } linera-rpc = { workspace = true, features = ["server", "simple-network"] } -linera-sdk = { workspace = true, optional = true } +linera-sdk = { workspace = true } linera-storage.workspace = true linera-storage-service = { workspace = true, optional = true } linera-version.workspace = true diff --git a/linera-service/src/proxy/grpc.rs b/linera-service/src/proxy/grpc.rs index bef7e7c7701..a1caafdde3e 100644 --- a/linera-service/src/proxy/grpc.rs +++ b/linera-service/src/proxy/grpc.rs @@ -41,6 +41,7 @@ use linera_rpc::{ GRPC_MAX_MESSAGE_SIZE, }, }; +use linera_sdk::views::ViewError; use linera_storage::Storage; use prost::Message; use tokio::{select, task::JoinSet}; @@ -338,6 +339,30 @@ where } } } + + /// Returns the appropriate gRPC status for the given [`ViewError`]. + fn error_to_status(err: ViewError) -> Status { + let mut status = match &err { + ViewError::TooLargeValue | ViewError::Serialization(_) => { + Status::invalid_argument(err.to_string()) + } + ViewError::StoreError { .. } + | ViewError::TokioJoinError(_) + | ViewError::TryLockError(_) + | ViewError::InconsistentEntries + | ViewError::PostLoadValuesError + | ViewError::Io(_) => Status::internal(err.to_string()), + ViewError::KeyTooLong | ViewError::ArithmeticError(_) => { + Status::out_of_range(err.to_string()) + } + ViewError::NotFound(_) + | ViewError::BlobNotFoundOnRead(_) + | ViewError::CannotAcquireCollectionEntry + | ViewError::MissingEntries => Status::not_found(err.to_string()), + }; + status.set_source(Arc::new(err)); + status + } } #[async_trait] @@ -443,7 +468,7 @@ where .storage .read_blob(blob_id) .await - .map_err(|err| Status::from_error(Box::new(err)))?; + .map_err(Self::error_to_status)?; Ok(Response::new(blob.into_inner_content().try_into()?)) } @@ -458,7 +483,7 @@ where .storage .read_hashed_certificate_value(hash) .await - .map_err(|err| Status::from_error(Box::new(err)))?; + .map_err(Self::error_to_status)?; Ok(Response::new(certificate.try_into()?)) } @@ -473,7 +498,7 @@ where .storage .read_certificate(hash) .await - .map_err(|err| Status::from_error(Box::new(err)))?; + .map_err(Self::error_to_status)?; Ok(Response::new(certificate.try_into()?)) } @@ -502,7 +527,7 @@ where .storage .read_certificates(batch.to_vec()) .await - .map_err(|err| Status::from_error(Box::new(err)))? + .map_err(Self::error_to_status)? { if grpc_message_limiter.fits::(certificate.clone())? { certificates.push(certificate); @@ -528,7 +553,7 @@ where .storage .read_blob_state(blob_id) .await - .map_err(|err| Status::from_error(Box::new(err)))?; + .map_err(Self::error_to_status)?; Ok(Response::new(blob_state.last_used_by.into())) } }