use std::io;
use thiserror::Error;
use winapi::shared::winerror::ERROR_PARTIAL_COPY;
use crate::error::ExceptionCode;
#[derive(Debug, Error)]
#[cfg(feature = "rpc-core")]
#[cfg_attr(all(feature = "rpc-core", not(feature = "rpc-raw")), doc(hidden))]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "rpc-raw")))]
pub enum RawRpcError {
#[error("io error: {}", _0)]
Io(io::Error),
#[error("remote exception: {}", _0)]
RemoteException(ExceptionCode),
#[error("inaccessible target process")]
ProcessInaccessible,
#[error("inaccessible target module")]
ModuleInaccessible,
}
#[cfg(feature = "rpc-core")]
#[cfg_attr(all(feature = "rpc-core", not(feature = "rpc-raw")), doc(hidden))]
impl From<io::Error> for RawRpcError {
fn from(err: io::Error) -> Self {
if err.raw_os_error() == Some(ERROR_PARTIAL_COPY as _)
|| err.kind() == io::ErrorKind::PermissionDenied
{
Self::ProcessInaccessible
} else {
Self::Io(err)
}
}
}
#[cfg(feature = "rpc-core")]
#[cfg_attr(all(feature = "rpc-core", not(feature = "rpc-raw")), doc(hidden))]
impl From<ExceptionCode> for RawRpcError {
fn from(err: ExceptionCode) -> Self {
Self::RemoteException(err)
}
}
#[derive(Debug, Error)]
#[cfg(feature = "rpc-payload")]
#[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "rpc-payload")))]
pub enum PayloadRpcError {
#[error("io error: {}", _0)]
Io(io::Error),
#[error("remote exception: {}", _0)]
RemoteException(ExceptionCode),
#[error("inaccessible target process")]
ProcessInaccessible,
#[error("inaccessible target module")]
ModuleInaccessible,
#[error("remote procedure error: {}", _0)]
RemoteProcedure(String),
#[error("serde error: {}", _0)]
Serde(#[from] Box<bincode::ErrorKind>),
}
#[cfg(feature = "rpc-payload")]
impl From<io::Error> for PayloadRpcError {
fn from(err: io::Error) -> Self {
if err.raw_os_error() == Some(ERROR_PARTIAL_COPY as _)
|| err.kind() == io::ErrorKind::PermissionDenied
{
Self::ProcessInaccessible
} else {
Self::Io(err)
}
}
}
#[cfg(all(feature = "rpc-payload", feature = "rpc-raw"))]
impl From<RawRpcError> for PayloadRpcError {
fn from(err: RawRpcError) -> Self {
match err {
RawRpcError::Io(err) => Self::Io(err),
RawRpcError::RemoteException(code) => Self::RemoteException(code),
RawRpcError::ProcessInaccessible => Self::ProcessInaccessible,
RawRpcError::ModuleInaccessible => Self::ModuleInaccessible,
}
}
}