diff --git a/crates/libs/core/src/client/tests.rs b/crates/libs/core/src/client/tests.rs index 4e63a44..31cd2f8 100644 --- a/crates/libs/core/src/client/tests.rs +++ b/crates/libs/core/src/client/tests.rs @@ -73,7 +73,7 @@ async fn test_fabric_client() { let list = qc.get_node_list(&desc, timeout, Some(token.clone())); token.cancel(); let err = list.await.expect_err("request should be cancelled"); - assert_eq!(err, FabricErrorCode::OperationCanceled.into()); + assert_eq!(err, FabricErrorCode::E_ABORT.into()); } let smgr = c.get_service_manager(); diff --git a/crates/libs/core/src/error/errorcode.rs b/crates/libs/core/src/error/errorcode.rs new file mode 100644 index 0000000..134126c --- /dev/null +++ b/crates/libs/core/src/error/errorcode.rs @@ -0,0 +1,335 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License (MIT). See License.txt in the repo root for license information. +// ------------------------------------------------------------ + +use mssf_com::FabricTypes::FABRIC_ERROR_CODE; +use windows_core::HRESULT; + +use super::FabricError; + +// Common HRESULT codes that SF reuses from windows. +const S_OK: FABRIC_ERROR_CODE = FABRIC_ERROR_CODE(windows::Win32::Foundation::S_OK.0); +const E_ABORT: FABRIC_ERROR_CODE = FABRIC_ERROR_CODE(windows::Win32::Foundation::E_ABORT.0); +const E_ACCESSDENIED: FABRIC_ERROR_CODE = + FABRIC_ERROR_CODE(windows::Win32::Foundation::E_ACCESSDENIED.0); +const E_FAIL: FABRIC_ERROR_CODE = FABRIC_ERROR_CODE(windows::Win32::Foundation::E_FAIL.0); +const E_HANDLE: FABRIC_ERROR_CODE = FABRIC_ERROR_CODE(windows::Win32::Foundation::E_HANDLE.0); +const E_INVALIDARG: FABRIC_ERROR_CODE = + FABRIC_ERROR_CODE(windows::Win32::Foundation::E_INVALIDARG.0); +const E_NOINTERFACE: FABRIC_ERROR_CODE = + FABRIC_ERROR_CODE(windows::Win32::Foundation::E_NOINTERFACE.0); +const E_NOTIMPL: FABRIC_ERROR_CODE = FABRIC_ERROR_CODE(windows::Win32::Foundation::E_NOTIMPL.0); +const E_OUTOFMEMORY: FABRIC_ERROR_CODE = + FABRIC_ERROR_CODE(windows::Win32::Foundation::E_OUTOFMEMORY.0); +const E_POINTER: FABRIC_ERROR_CODE = FABRIC_ERROR_CODE(windows::Win32::Foundation::E_POINTER.0); +const E_UNEXPECTED: FABRIC_ERROR_CODE = + FABRIC_ERROR_CODE(windows::Win32::Foundation::E_UNEXPECTED.0); + +// HRESULT codes from win32 errors that SF resuses. +const E_FILE_EXISTS: FABRIC_ERROR_CODE = + FABRIC_ERROR_CODE(HRESULT::from_win32(windows::Win32::Foundation::ERROR_FILE_EXISTS.0).0); +const E_DIR_NOT_EMPTY: FABRIC_ERROR_CODE = + FABRIC_ERROR_CODE(HRESULT::from_win32(windows::Win32::Foundation::ERROR_DIR_NOT_EMPTY.0).0); +const E_NOT_FOUND: FABRIC_ERROR_CODE = + FABRIC_ERROR_CODE(HRESULT::from_win32(windows::Win32::Foundation::ERROR_NOT_FOUND.0).0); + +/// Hepler macro to define fabric error code. +/// SF uses win32 hresult code together with the custom fabric error code. +/// This enum helps passing errors between Rust and SF API, and is easy to debug. +/// code1 list are windows errors, lit is a dummy string literal, code list are fabric errors. +/// The macro defines windows errors first, then followed by fabric errors. +// Need to match cs impl: +// https://github.com/microsoft/service-fabric/blob/19791eb97c8d876517daa030e5a403f4bcad25b1/src/prod/src/managed/Api/src/System/Fabric/Interop/NativeTypes.cs#L57 +macro_rules! define_fabric_error_code{ + ($( $code1:ident ),* ,($lit:literal), $( $code:ident ),*) =>{ + #[allow(non_camel_case_types)] + #[derive(Debug, Clone)] + #[repr(i32)] + pub enum FabricErrorCode { + // Define windows error codes for SF + $( + $code1 = $code1 .0, + )* + + // defines SF error codes. + $( + $code = mssf_com::ServiceFabric::FabricTypes::$code .0, + )* + } + + impl TryFrom for FabricErrorCode { + type Error = &'static str; + + fn try_from(value: FABRIC_ERROR_CODE) -> Result { + match value { + $( + $code1 => Ok(Self::$code1), + )* + // SF code converts. + $( + mssf_com::ServiceFabric::FabricTypes::$code => Ok(Self::$code), + )* + _ => Err("Unknown FABRIC_ERROR_CODE") + } + } + } + } +} + +impl From for FabricError { + fn from(value: FabricErrorCode) -> Self { + FabricError(HRESULT(value as i32)) + } +} + +// other conversions goes through FabricError +impl From for HRESULT { + fn from(value: FabricErrorCode) -> Self { + FabricError::from(value).into() + } +} + +impl From for crate::Error { + fn from(value: FabricErrorCode) -> Self { + FabricError::from(value).into() + } +} + +impl core::fmt::Display for FabricErrorCode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + core::write!(f, "{:?}", self) // use the debug string + } +} + +// This defines all the fabric error codes. +// list copied from https://github.com/microsoft/service-fabric/blob/19791eb97c8d876517daa030e5a403f4bcad25b1/src/prod/src/idl/public/FabricTypes.idl#L60C18-L60C35 +define_fabric_error_code!( + S_OK, + E_ABORT, + E_ACCESSDENIED, + E_FAIL, + E_HANDLE, + E_INVALIDARG, + E_NOINTERFACE, + E_NOTIMPL, + E_OUTOFMEMORY, + E_POINTER, + E_UNEXPECTED, + E_FILE_EXISTS, + E_DIR_NOT_EMPTY, + E_NOT_FOUND, + ("Literal for breaking up first error chunk and the fabric errors"), + FABRIC_E_COMMUNICATION_ERROR, + FABRIC_E_INVALID_ADDRESS, + FABRIC_E_INVALID_NAME_URI, + FABRIC_E_INVALID_PARTITION_KEY, + FABRIC_E_NAME_ALREADY_EXISTS, + FABRIC_E_NAME_DOES_NOT_EXIST, + FABRIC_E_NAME_NOT_EMPTY, + FABRIC_E_NODE_NOT_FOUND, + FABRIC_E_NODE_IS_UP, + FABRIC_E_NO_WRITE_QUORUM, + FABRIC_E_NOT_PRIMARY, + FABRIC_E_NOT_READY, + FABRIC_E_OPERATION_NOT_COMPLETE, + FABRIC_E_PROPERTY_DOES_NOT_EXIST, + FABRIC_E_RECONFIGURATION_PENDING, + FABRIC_E_REPLICATION_QUEUE_FULL, + FABRIC_E_SERVICE_ALREADY_EXISTS, + FABRIC_E_SERVICE_DOES_NOT_EXIST, + FABRIC_E_SERVICE_OFFLINE, + FABRIC_E_SERVICE_METADATA_MISMATCH, + FABRIC_E_SERVICE_AFFINITY_CHAIN_NOT_SUPPORTED, + FABRIC_E_SERVICE_TYPE_ALREADY_REGISTERED, + FABRIC_E_SERVICE_TYPE_NOT_REGISTERED, + FABRIC_E_VALUE_TOO_LARGE, + FABRIC_E_VALUE_EMPTY, + FABRIC_E_PROPERTY_CHECK_FAILED, + FABRIC_E_WRITE_CONFLICT, + FABRIC_E_ENUMERATION_COMPLETED, + FABRIC_E_APPLICATION_TYPE_PROVISION_IN_PROGRESS, + FABRIC_E_APPLICATION_TYPE_ALREADY_EXISTS, + FABRIC_E_APPLICATION_TYPE_NOT_FOUND, + FABRIC_E_APPLICATION_TYPE_IN_USE, + FABRIC_E_APPLICATION_ALREADY_EXISTS, + FABRIC_E_APPLICATION_NOT_FOUND, + FABRIC_E_APPLICATION_UPGRADE_IN_PROGRESS, + FABRIC_E_APPLICATION_UPGRADE_VALIDATION_ERROR, + FABRIC_E_SERVICE_TYPE_NOT_FOUND, + FABRIC_E_SERVICE_TYPE_MISMATCH, + FABRIC_E_SERVICE_TYPE_TEMPLATE_NOT_FOUND, + FABRIC_E_CONFIGURATION_SECTION_NOT_FOUND, + FABRIC_E_CONFIGURATION_PARAMETER_NOT_FOUND, + FABRIC_E_INVALID_CONFIGURATION, + FABRIC_E_IMAGEBUILDER_VALIDATION_ERROR, + FABRIC_E_PARTITION_NOT_FOUND, + FABRIC_E_REPLICA_DOES_NOT_EXIST, + FABRIC_E_SERVICE_GROUP_ALREADY_EXISTS, + FABRIC_E_SERVICE_GROUP_DOES_NOT_EXIST, + FABRIC_E_PROCESS_DEACTIVATED, + FABRIC_E_PROCESS_ABORTED, + FABRIC_E_UPGRADE_FAILED, + FABRIC_E_INVALID_CREDENTIAL_TYPE, + FABRIC_E_INVALID_X509_FIND_TYPE, + FABRIC_E_INVALID_X509_STORE_LOCATION, + FABRIC_E_INVALID_X509_STORE_NAME, + FABRIC_E_INVALID_X509_THUMBPRINT, + FABRIC_E_INVALID_PROTECTION_LEVEL, + FABRIC_E_INVALID_X509_STORE, + FABRIC_E_INVALID_SUBJECT_NAME, + FABRIC_E_INVALID_ALLOWED_COMMON_NAME_LIST, + FABRIC_E_INVALID_CREDENTIALS, + FABRIC_E_DECRYPTION_FAILED, + FABRIC_E_CONFIGURATION_PACKAGE_NOT_FOUND, + FABRIC_E_DATA_PACKAGE_NOT_FOUND, + FABRIC_E_CODE_PACKAGE_NOT_FOUND, + FABRIC_E_SERVICE_ENDPOINT_RESOURCE_NOT_FOUND, + FABRIC_E_INVALID_OPERATION, + FABRIC_E_OBJECT_CLOSED, + FABRIC_E_TIMEOUT, + FABRIC_E_FILE_NOT_FOUND, + FABRIC_E_DIRECTORY_NOT_FOUND, + FABRIC_E_INVALID_DIRECTORY, + FABRIC_E_PATH_TOO_LONG, + FABRIC_E_IMAGESTORE_IOERROR, + FABRIC_E_CORRUPTED_IMAGE_STORE_OBJECT_FOUND, + FABRIC_E_APPLICATION_NOT_UPGRADING, + FABRIC_E_APPLICATION_ALREADY_IN_TARGET_VERSION, + FABRIC_E_IMAGEBUILDER_UNEXPECTED_ERROR, + FABRIC_E_FABRIC_VERSION_NOT_FOUND, + FABRIC_E_FABRIC_VERSION_IN_USE, + FABRIC_E_FABRIC_VERSION_ALREADY_EXISTS, + FABRIC_E_FABRIC_ALREADY_IN_TARGET_VERSION, + FABRIC_E_FABRIC_NOT_UPGRADING, + FABRIC_E_FABRIC_UPGRADE_IN_PROGRESS, + FABRIC_E_FABRIC_UPGRADE_VALIDATION_ERROR, + FABRIC_E_HEALTH_MAX_REPORTS_REACHED, + FABRIC_E_HEALTH_STALE_REPORT, + FABRIC_E_KEY_TOO_LARGE, + FABRIC_E_KEY_NOT_FOUND, + FABRIC_E_SEQUENCE_NUMBER_CHECK_FAILED, + FABRIC_E_ENCRYPTION_FAILED, + FABRIC_E_INVALID_ATOMIC_GROUP, + FABRIC_E_HEALTH_ENTITY_NOT_FOUND, + FABRIC_E_SERVICE_MANIFEST_NOT_FOUND, + FABRIC_E_RELIABLE_SESSION_TRANSPORT_STARTUP_FAILURE, + FABRIC_E_RELIABLE_SESSION_ALREADY_EXISTS, + FABRIC_E_RELIABLE_SESSION_CANNOT_CONNECT, + FABRIC_E_RELIABLE_SESSION_MANAGER_EXISTS, + FABRIC_E_RELIABLE_SESSION_REJECTED, + FABRIC_E_RELIABLE_SESSION_MANAGER_ALREADY_LISTENING, + FABRIC_E_RELIABLE_SESSION_MANAGER_NOT_FOUND, + FABRIC_E_RELIABLE_SESSION_MANAGER_NOT_LISTENING, + FABRIC_E_INVALID_SERVICE_TYPE, + FABRIC_E_IMAGEBUILDER_TIMEOUT, + FABRIC_E_IMAGEBUILDER_ACCESS_DENIED, + FABRIC_E_IMAGEBUILDER_INVALID_MSI_FILE, + FABRIC_E_SERVICE_TOO_BUSY, + FABRIC_E_TRANSACTION_NOT_ACTIVE, + FABRIC_E_REPAIR_TASK_ALREADY_EXISTS, + FABRIC_E_REPAIR_TASK_NOT_FOUND, + FABRIC_E_RELIABLE_SESSION_NOT_FOUND, + FABRIC_E_RELIABLE_SESSION_QUEUE_EMPTY, + FABRIC_E_RELIABLE_SESSION_QUOTA_EXCEEDED, + FABRIC_E_RELIABLE_SESSION_SERVICE_FAULTED, + FABRIC_E_RELIABLE_SESSION_INVALID_TARGET_PARTITION, + FABRIC_E_TRANSACTION_TOO_LARGE, + FABRIC_E_REPLICATION_OPERATION_TOO_LARGE, + FABRIC_E_INSTANCE_ID_MISMATCH, + FABRIC_E_UPGRADE_DOMAIN_ALREADY_COMPLETED, + FABRIC_E_NODE_HAS_NOT_STOPPED_YET, + FABRIC_E_INSUFFICIENT_CLUSTER_CAPACITY, + FABRIC_E_INVALID_PACKAGE_SHARING_POLICY, + FABRIC_E_PREDEPLOYMENT_NOT_ALLOWED, + FABRIC_E_INVALID_BACKUP_SETTING, + FABRIC_E_MISSING_FULL_BACKUP, + FABRIC_E_BACKUP_IN_PROGRESS, + FABRIC_E_DUPLICATE_SERVICE_NOTIFICATION_FILTER_NAME, + FABRIC_E_INVALID_REPLICA_OPERATION, + FABRIC_E_INVALID_REPLICA_STATE, + FABRIC_E_LOADBALANCER_NOT_READY, + FABRIC_E_INVALID_PARTITION_OPERATION, + FABRIC_E_PRIMARY_ALREADY_EXISTS, + FABRIC_E_SECONDARY_ALREADY_EXISTS, + FABRIC_E_BACKUP_DIRECTORY_NOT_EMPTY, + FABRIC_E_FORCE_NOT_SUPPORTED_FOR_REPLICA_OPERATION, + FABRIC_E_ACQUIRE_FILE_LOCK_FAILED, + FABRIC_E_CONNECTION_DENIED, + FABRIC_E_SERVER_AUTHENTICATION_FAILED, + FABRIC_E_CONSTRAINT_KEY_UNDEFINED, + FABRIC_E_MULTITHREADED_TRANSACTIONS_NOT_ALLOWED, + FABRIC_E_INVALID_X509_NAME_LIST, + FABRIC_E_VERBOSE_FM_PLACEMENT_HEALTH_REPORTING_REQUIRED, + FABRIC_E_GATEWAY_NOT_REACHABLE, + FABRIC_E_USER_ROLE_CLIENT_CERTIFICATE_NOT_CONFIGURED, + FABRIC_E_TRANSACTION_ABORTED, + FABRIC_E_CANNOT_CONNECT, + FABRIC_E_MESSAGE_TOO_LARGE, + FABRIC_E_CONSTRAINT_NOT_SATISFIED, + FABRIC_E_ENDPOINT_NOT_FOUND, + FABRIC_E_APPLICATION_UPDATE_IN_PROGRESS, + FABRIC_E_DELETE_BACKUP_FILE_FAILED, + FABRIC_E_CONNECTION_CLOSED_BY_REMOTE_END, + FABRIC_E_INVALID_TEST_COMMAND_STATE, + FABRIC_E_TEST_COMMAND_OPERATION_ID_ALREADY_EXISTS, + FABRIC_E_CM_OPERATION_FAILED, + FABRIC_E_IMAGEBUILDER_RESERVED_DIRECTORY_ERROR, + FABRIC_E_CERTIFICATE_NOT_FOUND, + FABRIC_E_CHAOS_ALREADY_RUNNING, + FABRIC_E_FABRIC_DATA_ROOT_NOT_FOUND, + FABRIC_E_INVALID_RESTORE_DATA, + FABRIC_E_DUPLICATE_BACKUPS, + FABRIC_E_INVALID_BACKUP_CHAIN, + FABRIC_E_STOP_IN_PROGRESS, + FABRIC_E_ALREADY_STOPPED, + FABRIC_E_NODE_IS_DOWN, + FABRIC_E_NODE_TRANSITION_IN_PROGRESS, + FABRIC_E_INVALID_BACKUP, + FABRIC_E_INVALID_INSTANCE_ID, + FABRIC_E_INVALID_DURATION, + FABRIC_E_RESTORE_SAFE_CHECK_FAILED, + FABRIC_E_CONFIG_UPGRADE_FAILED, + FABRIC_E_UPLOAD_SESSION_RANGE_NOT_SATISFIABLE, + FABRIC_E_UPLOAD_SESSION_ID_CONFLICT, + FABRIC_E_INVALID_PARTITION_SELECTOR, + FABRIC_E_INVALID_REPLICA_SELECTOR, + FABRIC_E_DNS_SERVICE_NOT_FOUND, + FABRIC_E_INVALID_DNS_NAME, + FABRIC_E_DNS_NAME_IN_USE, + FABRIC_E_COMPOSE_DEPLOYMENT_ALREADY_EXISTS, + FABRIC_E_COMPOSE_DEPLOYMENT_NOT_FOUND, + FABRIC_E_INVALID_FOR_STATEFUL_SERVICES, + FABRIC_E_INVALID_FOR_STATELESS_SERVICES, + FABRIC_E_ONLY_VALID_FOR_STATEFUL_PERSISTENT_SERVICES, + FABRIC_E_INVALID_UPLOAD_SESSION_ID, + FABRIC_E_BACKUP_NOT_ENABLED, + FABRIC_E_BACKUP_IS_ENABLED, + FABRIC_E_BACKUP_POLICY_DOES_NOT_EXIST, + FABRIC_E_BACKUP_POLICY_ALREADY_EXISTS, + FABRIC_E_RESTORE_IN_PROGRESS, + FABRIC_E_RESTORE_SOURCE_TARGET_PARTITION_MISMATCH, + FABRIC_E_FAULT_ANALYSIS_SERVICE_NOT_ENABLED, + FABRIC_E_CONTAINER_NOT_FOUND, + FABRIC_E_OBJECT_DISPOSED, + FABRIC_E_NOT_READABLE, + FABRIC_E_BACKUPCOPIER_UNEXPECTED_ERROR, + FABRIC_E_BACKUPCOPIER_TIMEOUT, + FABRIC_E_BACKUPCOPIER_ACCESS_DENIED, + FABRIC_E_INVALID_SERVICE_SCALING_POLICY, + FABRIC_E_SINGLE_INSTANCE_APPLICATION_ALREADY_EXISTS, + FABRIC_E_SINGLE_INSTANCE_APPLICATION_NOT_FOUND, + FABRIC_E_VOLUME_ALREADY_EXISTS, + FABRIC_E_VOLUME_NOT_FOUND, + FABRIC_E_DATABASE_MIGRATION_IN_PROGRESS, + FABRIC_E_CENTRAL_SECRET_SERVICE_GENERIC, + FABRIC_E_SECRET_INVALID, + FABRIC_E_SECRET_VERSION_ALREADY_EXISTS, + FABRIC_E_SINGLE_INSTANCE_APPLICATION_UPGRADE_IN_PROGRESS, + FABRIC_E_OPERATION_NOT_SUPPORTED, + FABRIC_E_COMPOSE_DEPLOYMENT_NOT_UPGRADING, + FABRIC_E_SECRET_TYPE_CANNOT_BE_CHANGED, + FABRIC_E_NETWORK_NOT_FOUND, + FABRIC_E_NETWORK_IN_USE, + FABRIC_E_ENDPOINT_NOT_REFERENCED +); diff --git a/crates/libs/core/src/error/mod.rs b/crates/libs/core/src/error/mod.rs index 11eefc0..b37846b 100644 --- a/crates/libs/core/src/error/mod.rs +++ b/crates/libs/core/src/error/mod.rs @@ -4,17 +4,15 @@ // ------------------------------------------------------------ use crate::HRESULT; -use mssf_com::FabricTypes::{ - FABRIC_ERROR_CODE, FABRIC_E_OPERATION_NOT_COMPLETE, FABRIC_E_OPERATION_NOT_SUPPORTED, -}; -use windows::Win32::Foundation::{ - E_ABORT, E_ACCESSDENIED, E_FAIL, E_INVALIDARG, E_NOTIMPL, E_OUTOFMEMORY, E_POINTER, S_OK, -}; +use mssf_com::FabricTypes::FABRIC_ERROR_CODE; + +mod errorcode; +pub use errorcode::FabricErrorCode; /// Make passing error code to SF api easier. /// Provides conversion from windows errors or fabric error code /// to windows_core::Error. -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct FabricError(super::HRESULT); impl FabricError { @@ -47,40 +45,39 @@ impl From for HRESULT { } } -/// SF uses win32 hresult code together with the fabric error code. -/// See: https://github.com/microsoft/service-fabric/blob/master/src/prod/src/Common/ErrorCodeValue.h -/// We provide the common win32 hresult code that SF uses. They are helpful -/// when returning from Rust back into SF com api. -pub enum FabricErrorCode { - Success = S_OK.0 as isize, - InvalidArgument = E_INVALIDARG.0 as isize, - AccessDenied = E_ACCESSDENIED.0 as isize, - ArgumentNull = E_POINTER.0 as isize, - OperationCanceled = E_ABORT.0 as isize, - OperationFailed = E_FAIL.0 as isize, - OutOfMemory = E_OUTOFMEMORY.0 as isize, - NotImplemented = E_NOTIMPL.0 as isize, - // Some common errors from raw fabric code - AsyncOperationNotComplete = FABRIC_E_OPERATION_NOT_COMPLETE.0 as isize, - OperationNotSupported = FABRIC_E_OPERATION_NOT_SUPPORTED.0 as isize, // TODO: maybe all fabric error constants should be defined here as well in future. -} - -impl From for FabricError { - fn from(value: FabricErrorCode) -> Self { - FabricError(HRESULT(value as i32)) +impl From for FabricError { + fn from(error: crate::Error) -> Self { + Self(error.into()) } } -// other conversions goes through FabricError -impl From for HRESULT { - fn from(value: FabricErrorCode) -> Self { - FabricError::from(value).into() +impl core::fmt::Debug for FabricError { + fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut debug = fmt.debug_struct("FabricError"); + let str_code = match FabricErrorCode::try_from(FABRIC_ERROR_CODE(self.0 .0)) { + Ok(c) => Some(c), + Err(_) => None, + }; + debug.field("code", &self.0 .0); + match str_code { + Some(c) => debug.field("message", &c), + None => debug.field("message", &"unknown fabric error"), + }; + + debug.finish() } } -impl From for super::Error { - fn from(value: FabricErrorCode) -> Self { - FabricError::from(value).into() +impl core::fmt::Display for FabricError { + fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let str_code = match FabricErrorCode::try_from(FABRIC_ERROR_CODE(self.0 .0)) { + Ok(c) => Some(c), + Err(_) => None, + }; + match str_code { + Some(c) => core::write!(fmt, "{} ({})", c, self.0 .0), + None => core::write!(fmt, "{}", self.0 .0), + } } } @@ -95,17 +92,36 @@ mod test { #[test] fn test_fabric_error() { let fe = FabricError::from(FABRIC_E_CODE_PACKAGE_NOT_FOUND); + // check debug string + assert_eq!( + format!("{:?}", fe), + "FabricError { code: -2147017733, message: FABRIC_E_CODE_PACKAGE_NOT_FOUND }" + ); + // check display string + assert_eq!( + format!("{}", fe), + "FABRIC_E_CODE_PACKAGE_NOT_FOUND (-2147017733)" + ); let e = crate::Error::from(fe.clone()); assert_eq!(e.code(), fe.into()); } #[test] fn test_hresult_error() { - let err1: HRESULT = FabricError::from(FabricErrorCode::AccessDenied).into(); + let err1: HRESULT = FabricError::from(FabricErrorCode::E_ACCESSDENIED).into(); let err2 = E_ACCESSDENIED; assert_eq!(err1, err2); - let e: Error = FabricErrorCode::ArgumentNull.into(); + let e: Error = FabricErrorCode::E_POINTER.into(); assert_eq!(e, E_POINTER.into()); + + // use an error that is not fabric error + let fe = FabricError::from(windows::Win32::Foundation::SEC_E_INTERNAL_ERROR); + // check display string + assert_eq!(format!("{}", fe), "-2146893052"); + assert_eq!( + format!("{:?}", fe), + "FabricError { code: -2146893052, message: \"unknown fabric error\" }" + ); } } diff --git a/crates/libs/core/src/runtime/config.rs b/crates/libs/core/src/runtime/config.rs index 1318920..5556850 100644 --- a/crates/libs/core/src/runtime/config.rs +++ b/crates/libs/core/src/runtime/config.rs @@ -101,7 +101,7 @@ impl ConfigurationPackage { res.owner = Some(self.com.clone()); Ok(res) } - None => Err(FabricErrorCode::ArgumentNull.into()), + None => Err(FabricErrorCode::E_POINTER.into()), } } diff --git a/crates/libs/core/src/sync/cancel.rs b/crates/libs/core/src/sync/cancel.rs index 69d28f8..7854eb8 100644 --- a/crates/libs/core/src/sync/cancel.rs +++ b/crates/libs/core/src/sync/cancel.rs @@ -110,10 +110,10 @@ where Some(x) => Ok(x), None => { if !self.IsCompleted().as_bool() { - return Err(FabricErrorCode::AsyncOperationNotComplete.into()); + return Err(FabricErrorCode::FABRIC_E_OPERATION_NOT_COMPLETE.into()); } if self.token.is_cancelled() { - Err(FabricErrorCode::OperationCanceled.into()) + Err(FabricErrorCode::E_ABORT.into()) } else { panic!("content is consumed twice.") } @@ -238,7 +238,7 @@ impl Future for FabricReceiver2 { if let Err(e) = self.cancel_inner_ctx() { Poll::Ready(Err(e)) } else { - Poll::Ready(Err(FabricErrorCode::OperationCanceled.into())) + Poll::Ready(Err(FabricErrorCode::E_ABORT.into())) } } else { panic!("sender dropped without sending") @@ -437,10 +437,7 @@ mod test { let (tx, rx) = oneshot_channel::(Some(token.clone())); token.cancel(); std::mem::drop(tx); - assert_eq!( - rx.await.unwrap_err(), - FabricErrorCode::OperationCanceled.into() - ); + assert_eq!(rx.await.unwrap_err(), FabricErrorCode::E_ABORT.into()); } } @@ -490,7 +487,7 @@ mod test { select! { _ = t.cancelled() => { // The token was cancelled - Err(FabricErrorCode::OperationCanceled.into()) + Err(FabricErrorCode::E_ABORT.into()) } _ = tokio::time::sleep(delay) => { Ok(self.get_data()) @@ -519,7 +516,7 @@ mod test { select! { _ = t.cancelled() => { // The token was cancelled - Err(FabricErrorCode::OperationCanceled.into()) + Err(FabricErrorCode::E_ABORT.into()) } _ = tokio::time::sleep(delay) => { Ok(self.set_data(input)) @@ -701,7 +698,7 @@ mod test { let fu = obj.get_data_delay(Duration::from_secs(5), false, Some(token.clone())); token.cancel(); let err = fu.await.unwrap_err(); - assert_eq!(err, FabricErrorCode::OperationCanceled.into()); + assert_eq!(err, FabricErrorCode::E_ABORT.into()); } // get with cancel but ignore cancel from inner impl. // Because the cancel is ignored by inner implementation, success will be returned. @@ -724,7 +721,7 @@ mod test { ); token.cancel(); let err = fu.await.unwrap_err(); - assert_eq!(err, FabricErrorCode::OperationCanceled.into()); + assert_eq!(err, FabricErrorCode::E_ABORT.into()); } // because of cancel, data should not be changed. { diff --git a/crates/samples/echomain-stateful2/src/test.rs b/crates/samples/echomain-stateful2/src/test.rs index 0d9fa73..66016fc 100644 --- a/crates/samples/echomain-stateful2/src/test.rs +++ b/crates/samples/echomain-stateful2/src/test.rs @@ -104,7 +104,7 @@ impl TestClient { .collect::>(); if replicas.len() < 3 { // replica are not ready. - return Err(FabricErrorCode::OperationFailed.into()); + return Err(FabricErrorCode::E_FAIL.into()); } let stateful = replicas .iter() @@ -156,14 +156,14 @@ impl TestClient { let endpoints = partition.get_endpoint_list().iter().collect::>(); if endpoints.len() < 3 { // not available yet. - return Err(FabricErrorCode::OperationFailed.into()); + return Err(FabricErrorCode::E_FAIL.into()); } let primary = endpoints .iter() .find(|r| r.role == ServiceEndpointRole::StatefulPrimary); if primary.is_none() { // primary not available yet. - return Err(FabricErrorCode::OperationFailed.into()); + return Err(FabricErrorCode::E_FAIL.into()); } let secondary = endpoints .iter() diff --git a/crates/samples/echomain/src/test.rs b/crates/samples/echomain/src/test.rs index 1e4554f..f1dd4d9 100644 --- a/crates/samples/echomain/src/test.rs +++ b/crates/samples/echomain/src/test.rs @@ -85,7 +85,7 @@ impl EchoTestClient { _ => panic!("not stateless"), }), // replica might be restarting - None => Err(FabricErrorCode::OperationFailed.into()), + None => Err(FabricErrorCode::E_FAIL.into()), } }