systemless/error.rs
1//! Error types surfaced by the public API.
2
3use thiserror::Error;
4
5/// `Result<T, Error>` shorthand for any systemless operation.
6pub type Result<T> = std::result::Result<T, Error>;
7
8/// Top-level error returned by [`crate::runner::FixtureRunner`] and
9/// the supporting traps. Variants:
10///
11/// * [`Error::UnimplementedTrap`] — the dispatcher reached an A-line
12/// trap word with no matching handler. The trap word is included
13/// for diagnosis. Adding a `(is_tool, trap_num) =>` arm in the
14/// appropriate `src/trap/*.rs` file is how you fix this.
15///
16/// * [`Error::Halted`] — the guest application called `ExitToShell`
17/// (or otherwise reached a halt state). Not a failure per se;
18/// callers that loop on `run_steps` use `still_running == false`
19/// from the tuple instead of catching this.
20///
21/// * [`Error::Timeout`] — execution exceeded a caller-supplied
22/// instruction budget without halting. The carried `usize` is the
23/// instruction-count cap that was hit.
24///
25/// * [`Error::Oracle`] — recording-side error from the cross-runtime
26/// parity oracle (filesystem write, JSON serialisation, etc).
27/// Surfaces only when oracle recording is enabled via
28/// `enable_oracle_recording`.
29#[derive(Debug, Error)]
30pub enum Error {
31 /// The dispatcher reached an A-line trap word with no matching
32 /// handler. The trap word is included for diagnosis.
33 #[error("Unimplemented trap ${0:04X}")]
34 UnimplementedTrap(u16),
35
36 /// The guest application reached a halt state (typically via
37 /// `ExitToShell`).
38 #[error("Application halted")]
39 Halted,
40
41 /// Execution exceeded the caller-supplied instruction budget
42 /// without halting. The carried value is the instruction count
43 /// at the timeout.
44 #[error("Execution timeout after {0} instructions")]
45 Timeout(usize),
46
47 /// Cross-runtime parity oracle returned an error (filesystem
48 /// write, JSON serialisation, etc).
49 #[error("Oracle error: {0}")]
50 Oracle(String),
51}