Skip to main content

ax_api/
error.rs

1#[cfg(feature = "fs")]
2use ax_fs_ng::VfsError;
3use ax_io::IoError;
4#[cfg(feature = "net")]
5use ax_net::NetError;
6use ax_runtime::{RuntimeError, task::thread::TaskError};
7
8/// Errors owned by the public ArceOS API facade.
9#[derive(Clone, Copy, Debug, Eq, PartialEq, thiserror::Error)]
10pub enum ApiError {
11    /// A filesystem API failed in the VFS domain.
12    #[cfg(feature = "fs")]
13    #[error(transparent)]
14    Vfs(#[from] VfsError),
15    /// A socket API failed in the network domain.
16    #[cfg(feature = "net")]
17    #[error(transparent)]
18    Net(#[from] NetError),
19    /// A runtime-owned console operation failed.
20    #[error(transparent)]
21    Runtime(#[from] RuntimeError),
22    /// A scheduler operation failed in the task domain.
23    #[error(transparent)]
24    Task(#[from] TaskError),
25    /// A public API argument is outside its accepted domain.
26    #[error("invalid ArceOS API input")]
27    InvalidInput,
28    /// The selected object or policy does not support this operation.
29    #[error("ArceOS API operation is not supported")]
30    OperationNotSupported,
31    /// The scheduler rejected a priority update.
32    #[error("failed to update the current task priority")]
33    PriorityUpdateFailed,
34    /// The scheduler rejected an affinity update.
35    #[error("failed to update the current task affinity")]
36    AffinityUpdateFailed,
37}
38
39/// A result returned by the public ArceOS API facade.
40pub type ApiResult<T = ()> = Result<T, ApiError>;
41
42impl From<ApiError> for IoError {
43    fn from(error: ApiError) -> Self {
44        match error {
45            #[cfg(feature = "fs")]
46            ApiError::Vfs(error) => vfs_error_to_io_error(error),
47            #[cfg(feature = "net")]
48            ApiError::Net(error) => error.into(),
49            ApiError::Runtime(error) => runtime_error_to_io_error(error),
50            ApiError::Task(error) => task_error_to_io_error(error),
51            ApiError::InvalidInput => Self::InvalidInput,
52            ApiError::OperationNotSupported => Self::OperationNotSupported,
53            ApiError::PriorityUpdateFailed | ApiError::AffinityUpdateFailed => Self::BadState,
54        }
55    }
56}
57fn task_error_to_io_error(error: TaskError) -> IoError {
58    match error {
59        TaskError::InvalidConfiguration
60        | TaskError::InvalidCpuCount(_)
61        | TaskError::InvalidCpu(_)
62        | TaskError::InvalidNice(_)
63        | TaskError::InvalidRtPriority(_)
64        | TaskError::InvalidRoundRobinQuantum
65        | TaskError::InvalidDeadline { .. }
66        | TaskError::UnsupportedDeadlineFlags(_) => IoError::InvalidInput,
67        TaskError::DeadlineAdmission
68        | TaskError::DeadlineAffinity
69        | TaskError::ActiveTimerAffinity
70        | TaskError::ThreadBusy => IoError::ResourceBusy,
71        // Linux copy_process() reports the global thread limit as EAGAIN.
72        TaskError::ThreadCapacity => IoError::WouldBlock,
73        TaskError::TimerCapacity => IoError::NoMemory,
74        TaskError::UnsafeContext => IoError::OperationNotPermitted,
75        TaskError::StaleThreadId => IoError::NotFound,
76        TaskError::NotInitialized
77        | TaskError::InvalidRuntimeHandle
78        | TaskError::CpuOwnerBorrowed
79        | TaskError::CpuOwnerMismatch { .. }
80        | TaskError::ExecutorOwnerMismatch { .. }
81        | TaskError::CpuAlreadyOnline(_)
82        | TaskError::CpuOffline(_)
83        | TaskError::CpuNotQuiescent(_)
84        | TaskError::LastOnlineCpu(_)
85        | TaskError::InvalidTransition { .. }
86        | TaskError::AlreadyQueued
87        | TaskError::NotReady
88        | TaskError::NotExited
89        | TaskError::NoRunnableThread
90        | TaskError::InvalidPiState
91        | TaskError::InvalidPiWaitState(_)
92        | TaskError::PiCycle
93        | TaskError::PiChainLimit { .. }
94        | TaskError::RuntimeFailure(_) => IoError::BadState,
95    }
96}
97
98#[cfg(feature = "fs")]
99fn vfs_error_to_io_error(error: VfsError) -> IoError {
100    match error {
101        VfsError::AlreadyExists => IoError::AlreadyExists,
102        VfsError::BadAddress => IoError::BadAddress,
103        VfsError::BadFileDescriptor => IoError::BadFileDescriptor,
104        VfsError::BadState => IoError::BadState,
105        VfsError::CrossesDevices => IoError::CrossesDevices,
106        // These VFS categories have no exact `ax-io` representation. Keep
107        // them exact for VFS/POSIX callers and degrade only at this facade.
108        VfsError::DataMissing => IoError::InvalidData,
109        VfsError::DirectoryNotEmpty => IoError::DirectoryNotEmpty,
110        VfsError::FilesystemCorrupted => IoError::InvalidData,
111        VfsError::FilesystemLoop => IoError::FilesystemLoop,
112        VfsError::FileTooLarge => IoError::FileTooLarge,
113        VfsError::InvalidData => IoError::InvalidData,
114        VfsError::InvalidInput => IoError::InvalidInput,
115        VfsError::Interrupted => IoError::Interrupted,
116        VfsError::Io => IoError::Io,
117        VfsError::IsADirectory => IoError::IsADirectory,
118        VfsError::NameTooLong => IoError::NameTooLong,
119        VfsError::NoMemory => IoError::NoMemory,
120        VfsError::NoSuchDevice => IoError::NoSuchDevice,
121        VfsError::NoSuchDeviceOrAddress => IoError::NoSuchDeviceOrAddress,
122        VfsError::NotADirectory => IoError::NotADirectory,
123        VfsError::NotATty => IoError::NotATty,
124        VfsError::NotFound => IoError::NotFound,
125        VfsError::OperationNotPermitted => IoError::OperationNotPermitted,
126        VfsError::OperationNotSupported => IoError::OperationNotSupported,
127        VfsError::PermissionDenied => IoError::PermissionDenied,
128        VfsError::QuotaExceeded => IoError::StorageFull,
129        VfsError::ReadOnlyFilesystem => IoError::ReadOnlyFilesystem,
130        VfsError::ResourceBusy => IoError::ResourceBusy,
131        VfsError::StorageFull => IoError::StorageFull,
132        VfsError::TimedOut => IoError::TimedOut,
133        VfsError::TooManyLinks => IoError::Io,
134        VfsError::Unsupported => IoError::Unsupported,
135        VfsError::ValueOverflow => IoError::OutOfRange,
136        VfsError::WouldBlock => IoError::WouldBlock,
137    }
138}
139
140fn runtime_error_to_io_error(error: RuntimeError) -> IoError {
141    match error {
142        RuntimeError::ConsoleFailedClosed => IoError::BadState,
143        RuntimeError::SerialNotStarted => IoError::BadState,
144        RuntimeError::SerialControlBusy => IoError::ResourceBusy,
145        RuntimeError::WouldBlock => IoError::WouldBlock,
146        RuntimeError::OperationNotSupported => IoError::OperationNotSupported,
147        RuntimeError::InvalidCpu { .. } => IoError::InvalidInput,
148        _ => IoError::Io,
149    }
150}