Module error

Module error 

Source
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.
  • Bad input — the caller supplied invalid data; fix the request and try again.
  • Unrecoverable — the SDK is in a broken state; reinitialize.
  • 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§

ErrorContext
Error context carried by each SzError variant.

Enums§

ErrorCategory
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§

SzErrorInspect
Inspect any error chain for an embedded SzError.
SzResultExt
Extension trait for SzResult<T> providing error classification helpers.

Type Aliases§

SzResult
Result type alias for Senzing SDK operations