Skip to main content

brepkit_wasm/
error.rs

1//! WASM-boundary error types.
2//!
3//! [`WasmError`] aggregates errors from all lower layers. Because
4//! `wasm-bindgen` provides a blanket `impl<E: Error> From<E> for JsError`,
5//! any `WasmError` can be converted to `JsError` automatically via `?`.
6
7/// Errors that can occur in WASM-exposed operations.
8#[derive(Debug, thiserror::Error)]
9pub enum WasmError {
10    /// A JS-provided handle index does not correspond to a valid entity.
11    #[error("invalid {entity} handle: index {index} is out of bounds")]
12    InvalidHandle {
13        /// The kind of entity (e.g. "face", "solid").
14        entity: &'static str,
15        /// The raw index that was provided.
16        index: usize,
17    },
18
19    /// An input value is invalid (NaN, infinite, out of range, etc.).
20    #[error("invalid input: {reason}")]
21    InvalidInput {
22        /// Description of what is wrong.
23        reason: String,
24    },
25
26    /// An error from a modeling operation.
27    #[error(transparent)]
28    Operations(#[from] brepkit_operations::OperationsError),
29
30    /// An error from topology lookup.
31    #[error(transparent)]
32    Topology(#[from] brepkit_topology::TopologyError),
33
34    /// A math error (e.g. singular matrix).
35    #[error(transparent)]
36    Math(#[from] brepkit_math::MathError),
37}
38
39/// Validate that a `f64` value is finite (not NaN or infinite).
40///
41/// # Errors
42///
43/// Returns [`WasmError::InvalidInput`] if `value` is NaN or infinite.
44pub fn validate_finite(value: f64, name: &str) -> Result<(), WasmError> {
45    value
46        .is_finite()
47        .then_some(())
48        .ok_or_else(|| WasmError::InvalidInput {
49            reason: format!("{name} must be finite, got {value}"),
50        })
51}
52
53/// Validate that a `f64` value is finite and strictly positive.
54///
55/// # Errors
56///
57/// Returns [`WasmError::InvalidInput`] if `value` is NaN, infinite, zero,
58/// or negative.
59pub fn validate_positive(value: f64, name: &str) -> Result<(), WasmError> {
60    validate_finite(value, name)?;
61    (value > 0.0)
62        .then_some(())
63        .ok_or_else(|| WasmError::InvalidInput {
64            reason: format!("{name} must be positive, got {value}"),
65        })
66}