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
MathError enum with descriptive variants
- Convert
cross()1 to return Result<Self, MathError>
- Convert
rotate_matrix() to return Result<MatrixLike, MathError>
- Convert
determinant to return Result<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
Result returns
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
Notes
assert_eq! used for dimension matching in dot(), 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
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:
Axis unit vector check:
Determinant non-square check:
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
MathErrorenum with descriptive variantscross()1 to returnResult<Self, MathError>rotate_matrix()to returnResult<MatrixLike, MathError>determinantto returnResult<f32, MathError>assert!macros in math modules for similar conversions (And perhaps add features to selectively enable them)ResultreturnsProposed API
Updated function signatures
Migrations
Acceptance criteria
Vector::cross()returnsResult<Self, MathError>Vector::normalize()returnsResult<Self, MathError>(zero-length check)rotate_matrix()returnsResult<MatrixLike, MathError>Matrix::determinnantreturns <Result<f32, MathError>`Notes
assert_eq!used for dimension matching indot(),add(), etc. MAY remain as debug assertions since mismatched dimensions indicate programmer errordebug_assert!for internal invariants while using Result for user-facing validation