Errors and diagnostics
Softchat failures are stable, typed, and redacted. Branch on the error variant or code, never its display text, a generated-binding exception, relay prose, or an upstream cryptographic error.
Handling failures
- Rust
- Kotlin
- Android
- Swift
- TypeScript
match bob.decrypt_utf8(&message) {
Ok(plaintext) => display(plaintext),
Err(SoftchatError::DecryptionFailed) => discard_untrusted_message(),
Err(SoftchatError::IdentityErased) => require_reauthentication(),
Err(error) => record_code(error.code()),
}
try {
display(identity.decrypt(message))
} catch (_: SoftchatException.DecryptionFailed) {
discardUntrustedMessage()
} catch (_: SoftchatException.IdentityErased) {
requireReauthentication()
}
Map stable SoftchatException subclasses into domain failures before they
reach UI. Do not include input payloads in Crashlytics breadcrumbs or
WorkManager output data.
do {
display(try identity.decrypt(message))
} catch SoftchatError.decryptionFailed {
discardUntrustedMessage()
} catch SoftchatError.identityErased {
requireReauthentication()
}
try {
display(identity.decrypt(message));
} catch (error) {
if (error instanceof SoftchatError && error.code === "decryption_failed") {
discardUntrustedMessage();
} else {
throw error;
}
}
Retry categories
| Failure | Typical action |
|---|---|
| malformed, invalid, oversized, unsupported | permanent rejection of that input |
| authentication/decryption failure | discard untrusted value; do not reveal details |
| erased/closed/cancelled state | create a new authority or state object when policy permits |
relay retryable delivery | persist and retry under the session’s requested policy |
| external signer cancellation | return to the user flow without automatic signing retry |
| internal failure | record only build fingerprint, stable code, and safe host context |
Build fingerprint
The build fingerprint identifies the semantic version, source revision, protocol profile, target architecture, and target operating system. Include it with a bug report to distinguish package skew without logging account data.
- Rust
- Kotlin
- Android
- Swift
- TypeScript
let fingerprint = build_fingerprint();
val fingerprint = Softchat.buildFingerprint
val fingerprint = Softchat.buildFingerprint // exact installed AAR/native pair
let fingerprint = softchatBuildFingerprint
const fingerprint = buildFingerprint(); // after Wasm initialization
Diagnostics snapshot
The process-local snapshot reports aggregate operation counts, rejected operations, and input/output bytes. It deliberately excludes keys, plaintext, ciphertext, URLs, relay frames, event content, and identifiers.
- Rust
- Kotlin
- Android
- Swift
- TypeScript
let counters = diagnostics_snapshot();
val counters = Softchat.diagnosticsSnapshot()
val counters = Softchat.diagnosticsSnapshot()
Sample only under the application’s telemetry consent policy.
let counters = softchatDiagnosticsSnapshot()
const counters = diagnosticsSnapshot();
Diagnostics are counters, not an audit trail. If an application needs operation correlation, generate its own non-secret trace ID outside the SDK.