Skip to content

Commit b45e5c2

Browse files
committed
imp(sdk): remove snafu dependency
1 parent 8a15e2d commit b45e5c2

File tree

12 files changed

+185
-222
lines changed

12 files changed

+185
-222
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ postcard = { version = "1", features = ["alloc"] }
5858

5959
# Error handling
6060
snafu = { version = "0.8", features = ["backtrace"] }
61+
thiserror = "2"
6162

6263
# Concurrency
6364
parking_lot = "0.12"

crates/sdk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ serde = { workspace = true }
3131
serde_json = { workspace = true }
3232

3333
# Error handling
34-
snafu = { workspace = true }
34+
thiserror = { workspace = true }
3535

3636
# Concurrency
3737
parking_lot = { workspace = true }

crates/sdk/src/client.rs

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -949,10 +949,9 @@ impl VerifiedValue {
949949
pub fn verify(&self) -> Result<bool> {
950950
// Verify the Merkle proof against the block header's state root
951951
if !self.merkle_proof.verify(&self.block_header.state_root) {
952-
return Err(error::ProofVerificationSnafu {
952+
return Err(error::SdkError::ProofVerification {
953953
reason: "Merkle proof does not match state root",
954-
}
955-
.build());
954+
});
956955
}
957956

958957
// If we have a chain proof, that would be verified by the caller
@@ -1316,8 +1315,8 @@ impl LedgerClient {
13161315
let resolver = Arc::new(ServerResolver::new(source.clone()));
13171316

13181317
// Perform initial resolution
1319-
let servers = resolver.resolve().await.map_err(|e| {
1320-
error::ConfigSnafu { message: format!("Server discovery failed: {e}") }.build()
1318+
let servers = resolver.resolve().await.map_err(|e| error::SdkError::Config {
1319+
message: format!("Server discovery failed: {e}"),
13211320
})?;
13221321

13231322
// Convert to endpoint URLs
@@ -2156,35 +2155,32 @@ impl LedgerClient {
21562155
},
21572156
proto::WriteErrorCode::IdempotencyKeyReused => {
21582157
// Client reused idempotency key with different payload
2159-
crate::error::IdempotencySnafu {
2158+
Err(crate::error::SdkError::Idempotency {
21602159
message: format!(
21612160
"Idempotency key reused with different payload: {}",
21622161
error.message
21632162
),
2164-
conflict_key: None::<String>,
2163+
conflict_key: None,
21652164
original_tx_id: Some(Self::tx_id_to_hex(error.committed_tx_id.clone())),
2166-
}
2167-
.fail()
2165+
})
21682166
},
21692167
_ => {
21702168
// Other write errors (CAS failures, etc.)
2171-
crate::error::RpcSnafu {
2169+
Err(crate::error::SdkError::Rpc {
21722170
code: tonic::Code::FailedPrecondition,
21732171
message: error.message,
2174-
request_id: None::<String>,
2175-
trace_id: None::<String>,
2176-
}
2177-
.fail()
2172+
request_id: None,
2173+
trace_id: None,
2174+
})
21782175
},
21792176
}
21802177
},
2181-
None => crate::error::RpcSnafu {
2178+
None => Err(crate::error::SdkError::Rpc {
21822179
code: tonic::Code::Internal,
2183-
message: "Empty write response".to_string(),
2184-
request_id: None::<String>,
2185-
trace_id: None::<String>,
2186-
}
2187-
.fail(),
2180+
message: "Empty write response".to_owned(),
2181+
request_id: None,
2182+
trace_id: None,
2183+
}),
21882184
}
21892185
}
21902186

@@ -2408,35 +2404,32 @@ impl LedgerClient {
24082404
},
24092405
proto::WriteErrorCode::IdempotencyKeyReused => {
24102406
// Client reused idempotency key with different payload
2411-
crate::error::IdempotencySnafu {
2407+
Err(crate::error::SdkError::Idempotency {
24122408
message: format!(
24132409
"Idempotency key reused with different payload: {}",
24142410
error.message
24152411
),
2416-
conflict_key: None::<String>,
2412+
conflict_key: None,
24172413
original_tx_id: Some(Self::tx_id_to_hex(error.committed_tx_id.clone())),
2418-
}
2419-
.fail()
2414+
})
24202415
},
24212416
_ => {
24222417
// Other write errors (CAS failures, etc.)
2423-
crate::error::RpcSnafu {
2418+
Err(crate::error::SdkError::Rpc {
24242419
code: tonic::Code::FailedPrecondition,
24252420
message: error.message,
2426-
request_id: None::<String>,
2427-
trace_id: None::<String>,
2428-
}
2429-
.fail()
2421+
request_id: None,
2422+
trace_id: None,
2423+
})
24302424
},
24312425
}
24322426
},
2433-
None => crate::error::RpcSnafu {
2427+
None => Err(crate::error::SdkError::Rpc {
24342428
code: tonic::Code::Internal,
2435-
message: "Empty batch write response".to_string(),
2436-
request_id: None::<String>,
2437-
trace_id: None::<String>,
2438-
}
2439-
.fail(),
2429+
message: "Empty batch write response".to_owned(),
2430+
request_id: None,
2431+
trace_id: None,
2432+
}),
24402433
}
24412434
}
24422435

@@ -3030,7 +3023,9 @@ impl LedgerClient {
30303023
match result.status {
30313024
HealthStatus::Healthy => Ok(true),
30323025
HealthStatus::Degraded => Ok(false),
3033-
HealthStatus::Unavailable => error::UnavailableSnafu { message: result.message }.fail(),
3026+
HealthStatus::Unavailable => {
3027+
Err(error::SdkError::Unavailable { message: result.message })
3028+
},
30343029
HealthStatus::Unspecified => Ok(false),
30353030
}
30363031
}

crates/sdk/src/config.rs

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ use std::time::Duration;
44

55
use bon::bon;
66
use inferadb_ledger_types::config::ValidationConfig;
7-
use snafu::ensure;
87

98
use crate::{
10-
error::{ConfigSnafu, InvalidUrlSnafu, Result},
9+
error::{Result, SdkError},
1110
server::ServerSource,
1211
tracing::TraceConfig,
1312
};
@@ -117,24 +116,27 @@ impl ClientConfig {
117116
) -> Result<Self> {
118117
// Validate static endpoints
119118
if let ServerSource::Static(ref endpoints) = servers {
120-
ensure!(
121-
!endpoints.is_empty(),
122-
ConfigSnafu {
119+
if endpoints.is_empty() {
120+
return Err(SdkError::Config {
123121
message: "at least one endpoint is required for static server source"
124-
}
125-
);
122+
.to_owned(),
123+
});
124+
}
126125

127126
for endpoint in endpoints {
128127
validate_url(endpoint)?;
129128
}
130129
}
131130

132-
ensure!(!client_id.is_empty(), ConfigSnafu { message: "client_id cannot be empty" });
133-
ensure!(!timeout.is_zero(), ConfigSnafu { message: "timeout cannot be zero" });
134-
ensure!(
135-
!connect_timeout.is_zero(),
136-
ConfigSnafu { message: "connect_timeout cannot be zero" }
137-
);
131+
if client_id.is_empty() {
132+
return Err(SdkError::Config { message: "client_id cannot be empty".to_owned() });
133+
}
134+
if timeout.is_zero() {
135+
return Err(SdkError::Config { message: "timeout cannot be zero".to_owned() });
136+
}
137+
if connect_timeout.is_zero() {
138+
return Err(SdkError::Config { message: "connect_timeout cannot be zero".to_owned() });
139+
}
138140

139141
Ok(Self {
140142
servers,
@@ -285,19 +287,28 @@ impl RetryPolicy {
285287
fn validate_url(url: &str) -> Result<()> {
286288
// Basic validation - must start with http:// or https://
287289
if !url.starts_with("http://") && !url.starts_with("https://") {
288-
return InvalidUrlSnafu { url, message: "URL must start with http:// or https://" }.fail();
290+
return Err(SdkError::InvalidUrl {
291+
url: url.to_owned(),
292+
message: "URL must start with http:// or https://".to_owned(),
293+
});
289294
}
290295

291296
// Check there's something after the scheme
292297
let rest = url.strip_prefix("http://").or_else(|| url.strip_prefix("https://")).unwrap_or("");
293298

294299
if rest.is_empty() {
295-
return InvalidUrlSnafu { url, message: "URL must have a host" }.fail();
300+
return Err(SdkError::InvalidUrl {
301+
url: url.to_owned(),
302+
message: "URL must have a host".to_owned(),
303+
});
296304
}
297305

298306
// Check for invalid characters
299307
if rest.contains(char::is_whitespace) {
300-
return InvalidUrlSnafu { url, message: "URL cannot contain whitespace" }.fail();
308+
return Err(SdkError::InvalidUrl {
309+
url: url.to_owned(),
310+
message: "URL cannot contain whitespace".to_owned(),
311+
});
301312
}
302313

303314
Ok(())
@@ -501,13 +512,16 @@ impl TlsConfig {
501512
) -> Result<Self> {
502513
// If client cert is set, key must also be set
503514
if client_cert.is_some() && client_key.is_none() {
504-
return ConfigSnafu { message: "client certificate requires a private key" }.fail();
515+
return Err(SdkError::Config {
516+
message: "client certificate requires a private key".to_owned(),
517+
});
505518
}
506519

507520
// Must have some way to verify server certificate
508521
if ca_cert.is_none() && !use_native_roots {
509-
return ConfigSnafu { message: "TLS requires either a CA certificate or native roots" }
510-
.fail();
522+
return Err(SdkError::Config {
523+
message: "TLS requires either a CA certificate or native roots".to_owned(),
524+
});
511525
}
512526

513527
Ok(Self { ca_cert, client_cert, client_key, domain_name, use_native_roots })

crates/sdk/src/connection.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,11 @@
2828
use std::{sync::Arc, time::Duration};
2929

3030
use parking_lot::RwLock;
31-
use snafu::ResultExt;
3231
use tonic::transport::{Certificate, Channel, ClientTlsConfig, Endpoint, Identity};
3332

3433
use crate::{
3534
config::ClientConfig,
36-
error::{ConnectionSnafu, InvalidUrlSnafu, Result, TransportSnafu},
35+
error::{Result, SdkError},
3736
server::{ServerSelector, ServerSource},
3837
};
3938

@@ -186,28 +185,25 @@ impl ConnectionPool {
186185
};
187186

188187
let Some(endpoint_url) = endpoint_url else {
189-
return ConnectionSnafu {
188+
return Err(SdkError::Connection {
190189
message:
191190
"No endpoints available. For DNS/File sources, ensure the resolver has run."
192-
.to_string(),
193-
}
194-
.fail();
191+
.to_owned(),
192+
});
195193
};
196194

197195
// Parse the endpoint URL
198-
let endpoint = Endpoint::try_from(endpoint_url.clone()).map_err(|_| {
199-
InvalidUrlSnafu {
196+
let endpoint =
197+
Endpoint::try_from(endpoint_url.clone()).map_err(|_| SdkError::InvalidUrl {
200198
url: endpoint_url.clone(),
201-
message: "Failed to parse as tonic endpoint".to_string(),
202-
}
203-
.build()
204-
})?;
199+
message: "Failed to parse as tonic endpoint".to_owned(),
200+
})?;
205201

206202
// Apply connection settings (including TLS if configured)
207203
let endpoint = self.configure_endpoint(endpoint)?;
208204

209205
// Establish the connection
210-
let channel = endpoint.connect().await.context(TransportSnafu)?;
206+
let channel = endpoint.connect().await?;
211207

212208
Ok(channel)
213209
}
@@ -230,8 +226,8 @@ impl ConnectionPool {
230226
// Apply TLS configuration if present
231227
let endpoint = if let Some(ref tls_config) = self.config.tls {
232228
let tls = self.build_tls_config(tls_config)?;
233-
endpoint.tls_config(tls).map_err(|e| {
234-
ConnectionSnafu { message: format!("TLS configuration error: {e}") }.build()
229+
endpoint.tls_config(tls).map_err(|e| SdkError::Connection {
230+
message: format!("TLS configuration error: {e}"),
235231
})?
236232
} else {
237233
endpoint

crates/sdk/src/discovery.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use tracing::{debug, info, warn};
5757
use crate::{
5858
config::DiscoveryConfig,
5959
connection::ConnectionPool,
60-
error::{Result, RpcSnafu},
60+
error::{Result, SdkError},
6161
retry::with_retry,
6262
};
6363

@@ -216,14 +216,11 @@ impl DiscoveryService {
216216
let mut client = Self::create_discovery_client(channel, compression);
217217

218218
let request = proto::GetPeersRequest { max_peers };
219-
let response = client.get_peers(request).await.map_err(|status| {
220-
RpcSnafu {
221-
code: status.code(),
222-
message: status.message().to_string(),
223-
request_id: None::<String>,
224-
trace_id: None::<String>,
225-
}
226-
.build()
219+
let response = client.get_peers(request).await.map_err(|status| SdkError::Rpc {
220+
code: status.code(),
221+
message: status.message().to_owned(),
222+
request_id: None,
223+
trace_id: None,
227224
})?;
228225

229226
let inner = response.into_inner();

0 commit comments

Comments
 (0)