Skip to content

Commit a741164

Browse files
committed
RSCBC-252: Treat unknown scope errors the same as unknown collection
1 parent 0bfdd63 commit a741164

File tree

5 files changed

+84
-2
lines changed

5 files changed

+84
-2
lines changed

sdk/couchbase-core/src/collectionresolver.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ where
8282
if let Some(memdx_err) = err.is_memdx_error() {
8383
if memdx_err.is_server_error_kind(ServerErrorKind::UnknownCollectionID)
8484
|| memdx_err.is_server_error_kind(ServerErrorKind::UnknownCollectionName)
85+
|| memdx_err.is_server_error_kind(ServerErrorKind::UnknownScopeName)
8586
{
8687
resolver
8788
.invalidate_collection_id(scope_name, collection_name)

sdk/couchbase-core/src/crudcomponent.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -954,7 +954,9 @@ impl<
954954
};
955955

956956
if let Some(memdx_err) = err.is_memdx_error() {
957-
if memdx_err.is_server_error_kind(ServerErrorKind::UnknownCollectionName) {
957+
if memdx_err.is_server_error_kind(ServerErrorKind::UnknownCollectionName)
958+
|| memdx_err.is_server_error_kind(ServerErrorKind::UnknownScopeName)
959+
{
958960
return Err(err);
959961
}
960962
}

sdk/couchbase-core/src/retry.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ fn server_error_to_retry_reason(rs: &Arc<RetryManager>, e: &ServerError) -> Opti
354354
ServerErrorKind::UnknownCollectionName => {
355355
return Some(RetryReason::KvCollectionOutdated);
356356
}
357+
ServerErrorKind::UnknownScopeName => {
358+
return Some(RetryReason::KvCollectionOutdated);
359+
}
357360
ServerErrorKind::Locked => {
358361
return Some(RetryReason::KvLocked);
359362
}

sdk/couchbase-core/tests/agent_ops.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::common::default_agent_options::{create_default_options, create_option
2222
use crate::common::helpers::try_until;
2323
use crate::common::helpers::{
2424
create_collection_and_wait_for_kv, delete_collection_and_wait_for_kv, generate_bytes_value,
25-
generate_key, is_memdx_error,
25+
generate_key, generate_string_key, is_memdx_error,
2626
};
2727
use crate::common::test_config::{run_test, setup_test};
2828
use couchbase_core::agent::Agent;
@@ -778,3 +778,46 @@ fn test_changed_collection_id() {
778778
assert!(upsert_result.mutation_token.is_some());
779779
});
780780
}
781+
782+
#[test]
783+
fn test_unknown_scope() {
784+
setup_test(async |config| {
785+
let agent_opts = create_default_options(config.clone()).await;
786+
let scope_name = generate_string_key();
787+
let collection_name = generate_string_key();
788+
789+
let mut agent = Agent::new(agent_opts).await.unwrap();
790+
791+
let strat = Arc::new(BestEffortRetryStrategy::default());
792+
793+
let key = generate_key();
794+
let value = generate_bytes_value(32);
795+
796+
let upsert_opts = UpsertOptions::new(
797+
key.as_slice(),
798+
&scope_name,
799+
&collection_name,
800+
value.as_slice(),
801+
)
802+
.retry_strategy(strat);
803+
804+
try_until(
805+
Instant::now().add(Duration::from_secs(30)),
806+
Duration::from_millis(100),
807+
"upsert didn't fail with timeout in allowed time",
808+
|| async {
809+
let upsert_result = timeout_at(
810+
Instant::now().add(Duration::from_millis(2500)),
811+
agent.upsert(upsert_opts.clone()),
812+
)
813+
.await;
814+
815+
match upsert_result {
816+
Ok(_) => Ok(None),
817+
Err(_e) => Ok(Some(())),
818+
}
819+
},
820+
)
821+
.await;
822+
});
823+
}

sdk/couchbase-core/tests/common/helpers.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,39 @@ pub async fn delete_collection_and_wait_for_kv(
148148
timeout_at(deadline, fut()).await.unwrap();
149149
}
150150

151+
pub async fn delete_scope_and_wait_for_kv(
152+
agent: &Agent,
153+
bucket_name: &str,
154+
scope_name: &str,
155+
collection_name: &str,
156+
deadline: Instant,
157+
) {
158+
agent
159+
.delete_scope(&DeleteScopeOptions::new(bucket_name, scope_name))
160+
.await
161+
.unwrap();
162+
163+
let fut = || async {
164+
loop {
165+
let resp = agent
166+
.get_collection_id(GetCollectionIdOptions::new(scope_name, collection_name))
167+
.await;
168+
if let Some(e) = resp.err() {
169+
if is_memdx_error(&e)
170+
.unwrap()
171+
.is_server_error_kind(ServerErrorKind::UnknownScopeName)
172+
{
173+
break;
174+
}
175+
}
176+
177+
tokio::time::sleep(Duration::from_millis(100)).await;
178+
}
179+
};
180+
181+
timeout_at(deadline, fut()).await.unwrap();
182+
}
183+
151184
pub fn is_memdx_error(e: &Error) -> Option<&memdx::error::Error> {
152185
match e.kind() {
153186
ErrorKind::Memdx(err, ..) => Some(err),

0 commit comments

Comments
 (0)