Expand description
Handling errors from the Senzing SDK.
Every SDK method returns SzResult<T>, which is Result<T, SzError>.
When an operation fails, the SDK maps the native Senzing error code to the
appropriate SzError variant and includes the original error message.
§Deciding what to do with an error
The error hierarchy tells you how to respond:
- Retryable — temporary failure; the same call may succeed if you
retry after a brief delay.
DatabaseConnectionLost— connection droppedDatabaseTransient— deadlock, lock timeoutRetryTimeoutExceeded— internal retry budget exhausted
- Bad input — the caller supplied invalid data; fix the request and try again.
NotFound— entity or record does not existUnknownDataSource— data source not registered
- Unrecoverable — the SDK is in a broken state; reinitialize.
Database— permanent database failureLicense— license expired or invalidNotInitialized— SDK not yet initializedUnhandled— unexpected internal error
- Configuration — fix the configuration and reinitialize.
- ReplaceConflict — the default config was changed by another process.
§Handling errors from Senzing calls
§Quick classification
Use the boolean helpers to branch on error category:
use sz_rust_sdk::prelude::*;
use std::thread;
use std::time::Duration;
let record = r#"{"NAME_FULL": "John Smith"}"#;
match engine.add_record("CUSTOMERS", "1", record, None) {
Ok(info) => println!("Added: {info}"),
Err(ref e) if e.is_retryable() => {
eprintln!("Temporary failure, retrying: {e}");
thread::sleep(Duration::from_secs(1));
}
Err(ref e) if e.is_bad_input() => {
eprintln!("Bad input, skipping record: {e}");
}
Err(e) => return Err(e), // propagate everything else
}§Pattern matching on specific variants
use sz_rust_sdk::prelude::*;
match engine.get_record("CUSTOMERS", "CUST001", None) {
Ok(json) => println!("{json}"),
Err(SzError::NotFound(_)) => println!("Record does not exist"),
Err(SzError::UnknownDataSource(_)) => println!("Data source not registered"),
Err(e) => return Err(e),
}§Polymorphic category checking with ErrorCategory
Every error belongs to a hierarchy. SzError::is() checks whether
the error matches a category or any of its subtypes, so you can
write broad handlers without listing every variant:
use sz_rust_sdk::prelude::*;
// DatabaseTransient matches both its own category and the parent Retryable
let err = SzError::database_transient("Deadlock");
assert!(err.is(ErrorCategory::DatabaseTransient));
assert!(err.is(ErrorCategory::Retryable));§Retry loop with backoff
use sz_rust_sdk::prelude::*;
use std::thread;
use std::time::Duration;
fn add_with_retry(
engine: &dyn SzEngine,
json: &str,
max_retries: u32,
) -> SzResult<String> {
let mut attempt = 0;
loop {
match engine.add_record("CUSTOMERS", "1", json, None) {
Ok(info) => return Ok(info),
Err(ref e) if e.is_retryable() && attempt < max_retries => {
attempt += 1;
eprintln!("Retry {attempt}/{max_retries}: {e}");
thread::sleep(Duration::from_millis(100 * 2u64.pow(attempt)));
}
Err(e) => return Err(e),
}
}
}§Inspecting error details
Every SzError carries the native Senzing error code and message:
use sz_rust_sdk::prelude::*;
fn log_senzing_error(err: &SzError) {
eprintln!("Category: {}", err.category());
eprintln!("Severity: {}", err.severity());
eprintln!("Message: {}", err.message());
if let Some(code) = err.error_code() {
eprintln!("Native code: {code}");
}
}§Handling Senzing errors inside mixed-error functions
When a function calls both Senzing and non-Senzing operations (file I/O,
JSON parsing, HTTP, etc.), Rust’s ? operator needs a single error type
for the return — typically Result<T, Box<dyn Error>> or a custom enum.
The SzErrorInspect trait (automatically implemented for all error
types) walks the error chain to find and inspect any embedded SzError:
use sz_rust_sdk::prelude::*;
use std::fs;
fn load_from_file(
engine: &dyn SzEngine,
path: &str,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let data = fs::read_to_string(path)?; // io::Error on failure
engine.add_record("TEST", "1", &data, None)?; // SzError on failure
Ok(())
}
match load_from_file(&*engine, "data.json") {
Ok(()) => {}
Err(ref e) if e.is_sz_retryable() => eprintln!("Retry: {e}"),
Err(ref e) if e.is_sz_bad_input() => eprintln!("Bad input: {e}"),
Err(ref e) if e.is_sz_unrecoverable() => eprintln!("Fatal: {e}"),
Err(e) => eprintln!("Other error: {e}"),
}Use sz_error() to extract the underlying
SzError when you need full details:
use sz_rust_sdk::prelude::*;
fn log_error(err: &(dyn std::error::Error + 'static)) {
match err.sz_error() {
Some(sz) => {
eprintln!("[{}] {}", sz.category(), sz.message());
if let Some(code) = sz.error_code() {
eprintln!(" native code: {code}");
}
}
None => eprintln!("Non-Senzing error: {err}"),
}
}Structs§
- Error
Context - Error context carried by each
SzErrorvariant.
Enums§
- Error
Category - Error categories for hierarchy-based error handling.
- SzComponent
- Senzing SDK component for error reporting
- SzError
- The error type returned by all Senzing SDK operations.
Traits§
- SzError
Inspect - Inspect any error chain for an embedded
SzError. - SzResult
Ext - Extension trait for
SzResult<T>providing error classification helpers.
Type Aliases§
- SzResult
- Result type alias for Senzing SDK operations