-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
Overview
Replace panic! calls in public math functions with Result return types to allow callers to handle errors gracefully.
Current State
The math module contains several panics! throughout our math module:
Cross product dimension check:
// crates/lambda-rs/src/math/vector.rs:86-88
_ => {
panic!("Cross product is only defined for 3 dimensional vectors.")
}Axis unit vector check:
// crates/lambda-rs/src/math/matrix.rs:151-152
_ => {
panic!("Axis must be a unit vector")
}Determinant non-square check:
// crates/lambda-rs/src/math/matrix.rs:335
panic!("Cannot compute determinant of non-square matrix");These panics will cause programs implementing our math functions to crash, not allowing users to handle these errors within their own code without preventing the stack from unwinding (Which is not ideal for users to have to do).
Scope
- Define
MathErrorenum with descriptive variants - Convert
cross()1 to returnResult<Self, MathError> - Convert
rotate_matrix()to returnResult<MatrixLike, MathError> - Convert
determinantto returnResult<f32, MathError> - Review other
assert!macros in math modules for similar conversions (And perhaps add features to selectively enable them) - Update all current callers to handle
Resultreturns
Proposed API
// crates/lambda-rs/src/math/error.rs (new file)
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MathError {
/// Cross product requires exactly 3 dimensions.
CrossProductDimension { actual: usize },
/// Rotation axis must be a unit vector (one of [1,0,0], [0,1,0], [0,0,1]).
InvalidRotationAxis { axis: [i32; 3] },
/// Determinant requires a square matrix.
NonSquareMatrix { rows: usize, cols: usize },
/// Cannot normalize a zero-length vector.
ZeroLengthVector,
}
impl std::fmt::Display for MathError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MathError::CrossProductDimension { actual } => {
write!(f, "Cross product requires 3D vectors, got {}D", actual)
}
MathError::InvalidRotationAxis { axis } => {
write!(f, "Rotation axis {:?} is not a unit axis vector", axis)
}
MathError::NonSquareMatrix { rows, cols } => {
write!(f, "Determinant requires square matrix, got {}x{}", rows, cols)
}
MathError::ZeroLengthVector => {
write!(f, "Cannot normalize a zero-length vector")
}
}
}
}
impl std::error::Error for MathError {}Updated function signatures
// vector.rs
pub trait Vector {
// ...
fn cross(&self, other: &Self) -> Result<Self, MathError>;
fn normalize(&self) -> Result<Self, MathError>; // zero-length check
}
// matrix.rs
pub fn rotate_matrix<V, MatrixLike>(
matrix_to_rotate: MatrixLike,
axis: [f32; 3],
angle_in_turns: f32,
) -> Result<MatrixLike, MathError>;
pub trait Matrix<V> {
fn determinant(&self) -> Result<f32, MathError>;
}Migrations
// Before
let normal = direction.cross(&up);
// After (internal code that knows inputs are valid)
let normal = direction.cross(&up)
.expect("direction and up are both 3D vectors");
// Or propagate in user-facing code
let normal = direction.cross(&up)?;Acceptance criteria
- MathError enum with descriptive variants
- impl std::error::Error for MathError
-
Vector::cross()returnsResult<Self, MathError> -
Vector::normalize()returnsResult<Self, MathError>(zero-length check) -
rotate_matrix()returnsResult<MatrixLike, MathError> -
Matrix::determinnantreturns <Result<f32, MathError>` - Update tests
- Update internal and example usage
- Documentation updated to describe error conditions
Notes
assert_eq!used for dimension matching indot(),add(), etc. MAY remain as debug assertions since mismatched dimensions indicate programmer error- Consider keeping
debug_assert!for internal invariants while using Result for user-facing validation - Error messages MUST be actionable, describing what was expected vs. received when possible
Metadata
Metadata
Assignees
Labels
No labels