Skip to main content

Error

Enum Error 

Source
#[non_exhaustive]
pub enum Error {
Show 16 variants NotFound, StaleHandle, AccessDenied, ExclusiveAccess, PermissionDenied, Unsupported, Busy, StorageFull, Cancelled, Disconnected, DeviceReset, Timeout, NoDevice, InvalidData { message: String, }, Io { message: String, }, Other { detail: String, },
}
Expand description

The error type for high-level crate::mtp operations.

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

NotFound

The object or storage was not found (or never existed).

§

StaleHandle

A previously-valid handle is no longer valid because the device re-keyed it.

Notably Android’s MediaProvider re-keys object IDs across a media rescan, so a cached handle can be silently invalidated. The fix is to re-list the parent, re-resolve, and retry once — not to treat it as a hard not-found. See AGENTS.md.

§

AccessDenied

The operation was refused: read-only storage, write-protected object, or denied access.

§

ExclusiveAccess

Another process holds the device exclusively (e.g. ptpcamerad on macOS, or a busy claim).

Use this to guide users to close the conflicting app.

§

PermissionDenied

The OS denied permission to open the device.

Distinct from Error::ExclusiveAccess: nothing else holds the device — this user/process lacks permission to access it (most often missing Linux udev rules). Guide the user to fix device permissions rather than to close another app.

§

Unsupported

The device does not support this operation.

§

Busy

The device is temporarily busy; retrying may succeed.

§

StorageFull

The target storage is full.

§

Cancelled

The operation was cancelled (via a CancelToken or a stream cancel/drop).

§

Disconnected

The device was disconnected or stopped responding.

§

DeviceReset

A transfer cancel wedged the device, so the library reset it in software to recover. The current session is gone; reopen the device and continue.

Distinct from Disconnected: the device is still present and reopenable with no physical replug. Cancelling or abandoning an in-flight read triggers it on Android devices (issue #18), at any transfer size; prefer download_windowed, whose wedge is the recoverable one. Recover with quiet, idle-spaced reopens; see MtpDevice::reset_by_serial.

Don’t treat this as the only wedge signature. A Samsung reports it; a Pixel wedges the same way but the next operation simply hangs with no error at all (verified on a Pixel 9 Pro XL, macOS/nusb, 2026-07-20), so a consumer needs a timeout around operations too, not just this match. See docs/notes/android-wedges-and-the-reset-kill-switch.md.

§

Timeout

The operation timed out.

§

NoDevice

No matching device was found.

§

InvalidData

Data received from the device couldn’t be interpreted.

Fields

§message: String

What was invalid.

§

Io

An I/O error not covered by a more specific variant.

Fields

§message: String

The underlying message.

§

Other

A backend error without a more specific neutral mapping.

detail carries backend-specific text (a PTP response code, an HRESULT) for diagnostics only — don’t pattern-match on its contents.

Fields

§detail: String

Backend-specific diagnostic text.

Implementations§

Source§

impl Error

Source

pub fn invalid_data(message: impl Into<String>) -> Self

Create an Error::InvalidData with a message.

Source

pub fn is_retryable(&self) -> bool

Whether retrying the operation might succeed (transient failures).

Source

pub fn is_disconnected(&self) -> bool

Whether the device is gone and this handle is dead.

The check a long-lived consumer makes most: a daemon tears down the device’s mount, a file manager drops it from the sidebar. Pairs naturally with HotplugEvent::Left as the other way to learn the same thing.

Deliberately false for Error::DeviceReset, which is easy to lump in and shouldn’t be: there the device is still plugged in and reopenable with no replug, and only the session died. Treating it as a disconnect throws away a device that’s sitting right there. Reopen after a quiet pause instead (see Error::DeviceReset).

Source

pub fn is_exclusive_access(&self) -> bool

Whether another process holds the device exclusively.

Applications can use this to guide users to close the conflicting app (for example, query IORegistry for UsbExclusiveOwner on macOS).

Source

pub fn is_permission_denied(&self) -> bool

Whether the OS denied permission to access the device (e.g. missing Linux udev rules).

Distinct from is_exclusive_access: the remedy is to fix device permissions, not to close a conflicting app.

Source

pub fn is_stale_handle(&self) -> bool

Whether this is the Android “re-key” case where re-listing the parent and retrying once is the correct recovery (rather than treating it as not-found).

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

1.30.0 · 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<PtpError> for Error

Source§

fn from(e: PtpError) -> Self

Converts to this type from the input type.
Source§

impl From<UploadError> for Error

Source§

fn from(e: UploadError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl Freeze for Error

§

impl RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl UnsafeUnpin for Error

§

impl UnwindSafe 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<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<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: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> 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<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more