Skip to main content

Error

Enum Error 

Source
#[non_exhaustive]
pub enum Error {
Show 28 variants Protocol(ProtocolError), Io(Error), Runtime(String), RedirectUnsupported, InvalidRedirectData(String), ConnectRedirectLoop(u8), ListenerRefused(String), AllAddressesFailed(String), UnsupportedSni(String), UnexpectedPacket(u8), ConnectResendLoop(u8), FastAuthRequired, MissingSessionField(&'static str), CallTimeout(u32), NoRows, TooManyRows, Cancelled, ConnectionClosed(String), Tls(String), Wallet(WalletError), AccessTokenRequiresTcps, IamTokenProofOfPossession, TokenSource(TokenSourceError), UnsupportedAuthMode(UnsupportedAuthMode), SessionlessTransaction(SessionlessError), UnknownTransactionState(u32), Bind(BindError), Conversion(ConversionError),
}

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Protocol(ProtocolError)

§

Io(Error)

§

Runtime(String)

§

RedirectUnsupported

The listener redirected the connection to a target whose shape this driver refuses to follow: the redirect address demands a transport protocol CHANGE. Continuing a tcps connect over plain tcp would be a silent TLS downgrade, and a mid-connect tcp -> tcps upgrade is not supported; a redirect that keeps the original transport protocol is followed transparently.

§

InvalidRedirectData(String)

The listener answered CONNECT with a REDIRECT packet whose redirect data could not be understood (truncated length prefix, missing the NUL separator between the target address and its connect data, or an unparseable target address). The payload describes the defect; the raw redirect bytes are not echoed verbatim.

§

ConnectRedirectLoop(u8)

The listener kept answering every CONNECT with another REDIRECT. A real redirect chain is one hop (shared server / RAC); the bound only guards against a redirect loop between misconfigured listeners.

§

ListenerRefused(String)

§

AllAddressesFailed(String)

Every address in a multi-address connect descriptor (ADDRESS_LIST or several ADDRESS entries) failed to establish a transport. The payload aggregates the per-address failure reasons in the order they were tried. The connection never reached a listener, so there is nothing to reuse.

§

UnsupportedSni(String)

use_sni=true was explicitly requested but the Oracle TCPS SNI string (S{len}.{service}.V3.{version}) is not a valid rustls DNS name (its trailing all-numeric label is rejected by RFC-strict rustls), so it cannot be transmitted. The driver fails closed here instead of silently connecting without SNI. Reconnect with use_sni=false (the default) to rely on the post-handshake Oracle DN match, which secures the connection without SNI.

§

UnexpectedPacket(u8)

§

ConnectResendLoop(u8)

§

FastAuthRequired

§

MissingSessionField(&'static str)

§

CallTimeout(u32)

§

NoRows

§

TooManyRows

§

Cancelled

The in-flight operation was explicitly cancelled by the user (via Connection::cancel or by dropping a cancellable fetch future), the driver’s analog of the server-side ORA-01013 “user requested cancel of current operation”. Like a Self::CallTimeout (DPY-4024), a cancel drains the wire and leaves the session ALIVE and the connection clean and reusable: it is therefore not Self::is_connection_lost and is Self::is_transient (re-run the idempotent call on the same connection). It is distinguished from CallTimeout only so callers can tell a deliberate cancel apart from a deadline overrun.

§

ConnectionClosed(String)

The connection was closed because recovery from a prior failure could not complete: most commonly a second timeout while draining the server’s response after a Self::CallTimeout break (mirroring the reference ERR_CONNECTION_CLOSED raised when the post-break _receive_packet itself times out, protocol.pyx:454-458). Unlike Self::CallTimeout, the wire stream could not be left clean, so the connection is dead and must be discarded — Self::is_connection_lost is true for this variant. The payload is the human-readable reason.

§

Tls(String)

A TCPS/TLS transport error (wallet load, handshake, or server-cert / DN-match failure).

§

Wallet(WalletError)

A wallet-location or wallet-format error. Kept distinct from generic TLS failures so callers can classify unsupported wallet formats and operator setup issues without parsing strings.

§

AccessTokenRequiresTcps

Access-token authentication was requested over a non-TLS transport. A database access token must only travel over TCPS so it is not exposed in clear text (reference protocol.pyx ERR_ACCESS_TOKEN_REQUIRES_TCPS / DPY-3001). Reconnect with a tcps:// connect string. The token itself is never included in this error.

§

IamTokenProofOfPossession

The OCI IAM database-token proof-of-possession private key could not be used to sign the auth header: it was not a readable PKCS#8 RSA key, or the RSA-PKCS1v15-SHA256 signing operation failed. The key material, the token, and the signed header are never included in this error — only a fixed diagnostic is surfaced.

§

TokenSource(TokenSourceError)

A pluggable TokenSource failed to produce a database access token. The failure is a redacted TokenSourceError class; the token and any provider detail never appear in this error.

§

UnsupportedAuthMode(UnsupportedAuthMode)

The caller selected a known authentication mode that this thin build does not implement. The mode is structured so diagnostic tools can distinguish capability gaps from bad credentials, listener failures, or TLS setup errors without parsing the display string.

§

SessionlessTransaction(SessionlessError)

A sessionless transaction client-API misuse (reference ERR_SESSIONLESS_* / DPY-3034/3035/3036). The payload is the DPY full code so the shim can raise the matching DatabaseError.

§

UnknownTransactionState(u32)

A TPC (two-phase commit) state machine returned an unexpected out state (reference ERR_UNKNOWN_TRANSACTION_STATE / DPY-5010). The payload is the unexpected state value.

§

Bind(BindError)

A client-side bind payload was provably incompatible with the SQL text.

§

Conversion(ConversionError)

A typed FromSql conversion failed: the fetched value did not match the requested Rust type, was out of range, or could not be parsed. The payload describes the mismatch.

Implementations§

Source§

impl Error

Structured classification of an Error.

These accessors promote the driver’s internal retry knowledge (which ORA codes mean “the session died”, “the resource was busy”, “the cached plan is stale”) into a public, matchable taxonomy. python-oracledb gives you a bare .code integer and leaves the classification to you; here the curated lists ship with the driver so production retry / circuit-breaker code is trivial:

if err.is_connection_lost() {
    // reconnect, then retry
} else if err.is_retryable() {
    // back off and retry on the same connection
}

The classification sources, in priority order:

  1. The structured server error code (ServerErrorInfo.code) when present.
  2. Otherwise the ORA-NNNNN prefix parsed from the error message.

The curated transient and connection-lost code sets are maintained in this module and exposed through the stable methods below.

Source

pub fn kind(&self) -> ErrorKind

Stable top-level error category.

Source

pub fn resource_limit(&self) -> Option<ResourceLimit>

Structured resource-limit details when this error came from oracledb_protocol::wire::ProtocolLimits.

Source

pub fn ora_code(&self) -> Option<i32>

The Oracle error number (ORA-NNNNN) this error carries, if any.

Returns the structured ServerErrorInfo.code when the error came back on the structured path; otherwise it parses the ORA- prefix out of the server message. None for non-server errors (I/O, timeouts, protocol decode failures) and server messages with no ORA- code.

The value is an i32 (rather than u32) so it composes directly with the i32-typed codes most retry tables and logging layers already use; every real Oracle code fits comfortably.

Source

pub fn oracle_code(&self) -> Option<i32>

Alias for Self::ora_code using the API-design terminology.

Source

pub fn offset(&self) -> Option<i32>

The server-reported parse offset / error position for this error, if the server provided one (1-based character offset into the SQL text for a parse error). Only the structured server-error path retains the offset; None everywhere else, and None when the server reported offset 0.

Source

pub fn caret(&self, sql: &str) -> Option<String>

Render a compiler-style caret diagnostic for a parse error, pointing at the exact character in sql the server flagged (Error::offset):

ORA-00942: table or view does not exist
  |
1 | select * from no_such_table
  |               ^

Returns None when the error carries no parse offset (only structured server parse errors do). The headline is this error’s first Display line (the ORA- code + message). python-oracledb hands you a bare offset integer and leaves the rendering to you; this does it.

Source

pub fn connection_disposition(&self) -> ConnectionDisposition

Whether the connection that surfaced this error is still reusable. A dead disposition means the session was killed, the socket was reset, or the server reported one of the session-dead Oracle codes; callers should discard the connection before continuing.

Raw I/O errors (Error::Io) and the recovery-failure Error::ConnectionClosed also count as connection-lost: the transport is no longer usable.

A plain Error::CallTimeout is deliberately not connection-lost. On a call timeout the driver sends a BREAK, then drains the server’s in-flight response and the RESET handshake, leaving the wire stream clean and the connection reusable — exactly as python-oracledb does for DPY-4024 (ERR_CALL_TIMEOUT_EXCEEDED), which, unlike DPY-4011 (ERR_CONNECTION_CLOSED), does not set is_session_dead (errors.py:124-125). The connection survives; retry on the same one. Only when that drain itself fails (a second timeout) does the driver give up and surface Error::ConnectionClosed, which is connection-lost.

Source

pub fn is_connection_lost(&self) -> bool

Source

pub fn is_transient(&self) -> bool

Whether this error is transient: the operation failed for a reason expected to clear on its own (lock contention, deadlock victim, listener hand-off congestion, resource-manager throttle, or a call timeout), so the same call may be retried on the same connection after a short back-off. Does not include connection-lost codes (those need a reconnect first — use Self::is_connection_lost).

Error::CallTimeout is transient: after the driver drains the wire the connection is clean and reusable, so re-running the (idempotent) call on the same connection — e.g. with a longer timeout — is the natural retry. Error::Cancelled is transient for the same reason: an explicit cancel also drains the wire and leaves the session alive.

Source

pub fn retry_hint(&self) -> RetryHint

Conservative retry guidance. Any returned retry action still requires the caller to know the operation is idempotent; non-idempotent operations must not be replayed automatically.

Source

pub fn is_retryable(&self) -> bool

Trait Implementations§

Source§

impl Debug for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Error

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for Error

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<BindError> for Error

Source§

fn from(source: BindError) -> Self

Converts to this type from the input type.
Source§

impl From<ConversionError> for Error

Source§

fn from(err: ConversionError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for Error

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.
Source§

impl From<ProtocolError> for Error

Source§

fn from(source: ProtocolError) -> Self

Converts to this type from the input type.
Source§

impl From<WalletError> for Error

Source§

fn from(source: WalletError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Error

§

impl !UnwindSafe for Error

§

impl Freeze for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl UnsafeUnpin for Error

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, _span: NoopSpan) -> Self

Instruments this future with a span (no-op when disabled).
Source§

fn in_current_span(self) -> Self

Instruments this future with the current span (no-op when disabled).
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V