From 3e44659288214a52cb5df642ec27a887ddf8b08b Mon Sep 17 00:00:00 2001 From: Abdulla Abdurakhmanov Date: Thu, 30 May 2024 18:24:51 +0200 Subject: [PATCH] Handle sporadic tonic transport errors (#179) * Handle Tonic transport error with unknown status * Clippy fixes * Clippy fixes --- src/cache/backends/persistent_backend.rs | 8 +-- src/db/query_models.rs | 2 + src/errors.rs | 11 +++- src/firestore_serde/latlng_serializers.rs | 28 +++------ src/firestore_serde/reference_serializers.rs | 19 ++---- src/firestore_serde/serializer.rs | 63 +++++--------------- src/firestore_serde/timestamp_serializers.rs | 19 ++---- 7 files changed, 49 insertions(+), 101 deletions(-) diff --git a/src/cache/backends/persistent_backend.rs b/src/cache/backends/persistent_backend.rs index b538aa5..feff0fb 100644 --- a/src/cache/backends/persistent_backend.rs +++ b/src/cache/backends/persistent_backend.rs @@ -188,7 +188,7 @@ impl FirestorePersistentCacheBackend { fn write_document(&self, doc: &Document) -> FirestoreResult<()> { let (collection_path, document_id) = split_document_path(&doc.name); - if self.config.collections.get(collection_path).is_some() { + if self.config.collections.contains_key(collection_path) { let td: TableDefinition<&str, &[u8]> = TableDefinition::new(collection_path); let write_txn = self.redb.begin_write()?; @@ -338,7 +338,7 @@ impl FirestoreCacheDocsByPathSupport for FirestorePersistentCacheBackend { document_path: &str, ) -> FirestoreResult> { let (collection_path, document_id) = split_document_path(document_path); - if self.config.collections.get(collection_path).is_some() { + if self.config.collections.contains_key(collection_path) { let td: TableDefinition<&str, &[u8]> = TableDefinition::new(collection_path); let read_tx = self.redb.begin_read()?; let table = read_tx.open_table(td)?; @@ -359,7 +359,7 @@ impl FirestoreCacheDocsByPathSupport for FirestorePersistentCacheBackend { collection_path: &str, ) -> FirestoreResult>>> { - if self.config.collections.get(collection_path).is_some() { + if self.config.collections.contains_key(collection_path) { let td: TableDefinition<&str, &[u8]> = TableDefinition::new(collection_path); let read_tx = self.redb.begin_read()?; @@ -388,7 +388,7 @@ impl FirestoreCacheDocsByPathSupport for FirestorePersistentCacheBackend { query: &FirestoreQueryParams, ) -> FirestoreResult>>> { - if self.config.collections.get(collection_path).is_some() { + if self.config.collections.contains_key(collection_path) { // For now only basic/simple query all supported let simple_query_engine = FirestoreCacheQueryEngine::new(query); if simple_query_engine.params_supported() { diff --git a/src/db/query_models.rs b/src/db/query_models.rs index 943ac31..8fcf659 100644 --- a/src/db/query_models.rs +++ b/src/db/query_models.rs @@ -13,6 +13,7 @@ pub enum FirestoreQueryCollection { Group(Vec), } +#[allow(clippy::to_string_trait_impl)] impl ToString for FirestoreQueryCollection { fn to_string(&self) -> String { match self { @@ -312,6 +313,7 @@ pub enum FirestoreQueryDirection { Descending, } +#[allow(clippy::to_string_trait_impl)] impl ToString for FirestoreQueryDirection { fn to_string(&self) -> String { match self { diff --git a/src/errors.rs b/src/errors.rs index 8fa3e11..ae5df32 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -252,6 +252,15 @@ fn check_hyper_errors(status: gcloud_sdk::tonic::Status) -> FirestoreError { format!("Hyper error: {err}"), false, )), + _ if status.code() == gcloud_sdk::tonic::Code::Unknown + && status.message().contains("transport error") => + { + FirestoreError::DatabaseError(FirestoreDatabaseError::new( + FirestoreErrorPublicGenericDetails::new("CONNECTION_ERROR".into()), + format!("{status}"), + true, + )) + } _ => FirestoreError::DatabaseError(FirestoreDatabaseError::new( FirestoreErrorPublicGenericDetails::new(format!("{:?}", status.code())), format!("{status}"), @@ -260,7 +269,7 @@ fn check_hyper_errors(status: gcloud_sdk::tonic::Status) -> FirestoreError { }, _ => FirestoreError::DatabaseError(FirestoreDatabaseError::new( FirestoreErrorPublicGenericDetails::new(format!("{:?}", status.code())), - format!("{status}"), + format!("{status} without root cause"), false, )), } diff --git a/src/firestore_serde/latlng_serializers.rs b/src/firestore_serde/latlng_serializers.rs index d311dd7..69ca31d 100644 --- a/src/firestore_serde/latlng_serializers.rs +++ b/src/firestore_serde/latlng_serializers.rs @@ -30,14 +30,11 @@ pub fn serialize_latlng_for_firestore( type Ok = FirestoreValue; type Error = FirestoreError; - fn serialize_field( + fn serialize_field( &mut self, key: &'static str, value: &T, - ) -> Result<(), Self::Error> - where - T: Serialize, - { + ) -> Result<(), Self::Error> { let serializer = FirestoreValueSerializer { none_as_null: false, }; @@ -63,7 +60,7 @@ pub fn serialize_latlng_for_firestore( FirestoreSerializationError::from_message( "LatLng serializer doesn't recognize the structure of the object", ), - )) + )); } }; @@ -209,10 +206,7 @@ pub fn serialize_latlng_for_firestore( )) } - fn serialize_some(self, value: &T) -> Result - where - T: Serialize, - { + fn serialize_some(self, value: &T) -> Result { value.serialize(self) } @@ -235,27 +229,21 @@ pub fn serialize_latlng_for_firestore( self.serialize_str(variant) } - fn serialize_newtype_struct( + fn serialize_newtype_struct( self, _name: &'static str, value: &T, - ) -> Result - where - T: Serialize, - { + ) -> Result { value.serialize(self) } - fn serialize_newtype_variant( + fn serialize_newtype_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T, - ) -> Result - where - T: Serialize, - { + ) -> Result { Err(FirestoreError::SerializeError( FirestoreSerializationError::from_message( "LatLng serializer doesn't support this type", diff --git a/src/firestore_serde/reference_serializers.rs b/src/firestore_serde/reference_serializers.rs index 0a9a8a1..dfae40b 100644 --- a/src/firestore_serde/reference_serializers.rs +++ b/src/firestore_serde/reference_serializers.rs @@ -207,10 +207,7 @@ pub fn serialize_reference_for_firestore( } } - fn serialize_some(self, value: &T) -> Result - where - T: Serialize, - { + fn serialize_some(self, value: &T) -> Result { value.serialize(self) } @@ -233,27 +230,21 @@ pub fn serialize_reference_for_firestore( self.serialize_str(variant) } - fn serialize_newtype_struct( + fn serialize_newtype_struct( self, _name: &'static str, value: &T, - ) -> Result - where - T: Serialize, - { + ) -> Result { value.serialize(self) } - fn serialize_newtype_variant( + fn serialize_newtype_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T, - ) -> Result - where - T: Serialize, - { + ) -> Result { Err(FirestoreError::SerializeError( FirestoreSerializationError::from_message( "Reference serializer doesn't support this type", diff --git a/src/firestore_serde/serializer.rs b/src/firestore_serde/serializer.rs index fd20841..18714cf 100644 --- a/src/firestore_serde/serializer.rs +++ b/src/firestore_serde/serializer.rs @@ -176,10 +176,7 @@ impl serde::Serializer for FirestoreValueSerializer { } } - fn serialize_some(self, value: &T) -> Result - where - T: Serialize, - { + fn serialize_some(self, value: &T) -> Result { value.serialize(self) } @@ -202,14 +199,11 @@ impl serde::Serializer for FirestoreValueSerializer { self.serialize_str(variant) } - fn serialize_newtype_struct( + fn serialize_newtype_struct( self, name: &'static str, value: &T, - ) -> Result - where - T: Serialize, - { + ) -> Result { match name { crate::firestore_serde::timestamp_serializers::FIRESTORE_TS_TYPE_TAG_TYPE => { crate::firestore_serde::timestamp_serializers::serialize_timestamp_for_firestore( @@ -241,16 +235,13 @@ impl serde::Serializer for FirestoreValueSerializer { } } - fn serialize_newtype_variant( + fn serialize_newtype_variant( self, _name: &'static str, _variant_index: u32, variant: &'static str, value: &T, - ) -> Result - where - T: Serialize, - { + ) -> Result { let mut fields = HashMap::new(); fields.insert(String::from(variant), value.serialize(self)?.value); Ok(FirestoreValue::from( @@ -330,10 +321,7 @@ impl serde::ser::SerializeSeq for SerializeVec { type Ok = FirestoreValue; type Error = FirestoreError; - fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> - where - T: Serialize, - { + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> { let serialized_value = value .serialize(FirestoreValueSerializer { none_as_null: self.none_as_null, @@ -360,10 +348,7 @@ impl serde::ser::SerializeTuple for SerializeVec { type Ok = FirestoreValue; type Error = FirestoreError; - fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> - where - T: Serialize, - { + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> { serde::ser::SerializeSeq::serialize_element(self, value) } @@ -376,10 +361,7 @@ impl serde::ser::SerializeTupleStruct for SerializeVec { type Ok = FirestoreValue; type Error = FirestoreError; - fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> - where - T: Serialize, - { + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> { serde::ser::SerializeSeq::serialize_element(self, value) } @@ -392,10 +374,7 @@ impl serde::ser::SerializeTupleVariant for SerializeTupleVariant { type Ok = FirestoreValue; type Error = FirestoreError; - fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> - where - T: Serialize, - { + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> { let serialized_value = value .serialize(FirestoreValueSerializer { none_as_null: self.none_as_null, @@ -432,10 +411,7 @@ impl serde::ser::SerializeMap for SerializeMap { type Ok = FirestoreValue; type Error = FirestoreError; - fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> - where - T: Serialize, - { + fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> { let serializer = FirestoreValueSerializer { none_as_null: self.none_as_null, }; @@ -454,10 +430,7 @@ impl serde::ser::SerializeMap for SerializeMap { } } - fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> - where - T: Serialize, - { + fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> { match self.next_key.take() { Some(key) => { let serializer = FirestoreValueSerializer { @@ -492,14 +465,11 @@ impl serde::ser::SerializeStruct for SerializeMap { type Ok = FirestoreValue; type Error = FirestoreError; - fn serialize_field( + fn serialize_field( &mut self, key: &'static str, value: &T, - ) -> Result<(), Self::Error> - where - T: Serialize, - { + ) -> Result<(), Self::Error> { let serializer = FirestoreValueSerializer { none_as_null: self.none_as_null, }; @@ -527,14 +497,11 @@ impl serde::ser::SerializeStructVariant for SerializeStructVariant { type Ok = FirestoreValue; type Error = FirestoreError; - fn serialize_field( + fn serialize_field( &mut self, key: &'static str, value: &T, - ) -> Result<(), Self::Error> - where - T: Serialize, - { + ) -> Result<(), Self::Error> { let serializer = FirestoreValueSerializer { none_as_null: self.none_as_null, }; diff --git a/src/firestore_serde/timestamp_serializers.rs b/src/firestore_serde/timestamp_serializers.rs index ef08ac9..3a94f3d 100644 --- a/src/firestore_serde/timestamp_serializers.rs +++ b/src/firestore_serde/timestamp_serializers.rs @@ -231,10 +231,7 @@ pub fn serialize_timestamp_for_firestore( } } - fn serialize_some(self, value: &T) -> Result - where - T: Serialize, - { + fn serialize_some(self, value: &T) -> Result { value.serialize(self) } @@ -257,27 +254,21 @@ pub fn serialize_timestamp_for_firestore( self.serialize_str(variant) } - fn serialize_newtype_struct( + fn serialize_newtype_struct( self, _name: &'static str, value: &T, - ) -> Result - where - T: Serialize, - { + ) -> Result { value.serialize(self) } - fn serialize_newtype_variant( + fn serialize_newtype_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T, - ) -> Result - where - T: Serialize, - { + ) -> Result { Err(FirestoreError::SerializeError( FirestoreSerializationError::from_message( "Timestamp serializer doesn't support this type",