///|
/// Chains or wraps an error with an optional message
#inline
#callsite(autofill(loc))
#as_free_fn
pub fn[T] Cause::by(
err : Error,
msg? : String = "",
loc~ : SourceLoc,
) -> T raise Cause {
match err {
Cause(_) as cause => raise Causes(msg~, source=cause, loc~, err=Failure)
Causes(_) as cause => raise Causes(msg~, source=cause, loc~, err=Failure)
_ => raise Cause(msg~, source=err, loc~)
}
}
///|
priv suberror Failure {
Failure
} derive(Debug)
///|
/// Returns an `Iter` that walks the error chain
#cfg(any(target="wasm", target="js"))
pub fn Cause::errors(self : Cause) -> Iter[Cause] {
let mut cur : Cause? = Some(self)
Iter::new(fn() {
match cur {
None => None
Some(c) =>
match c {
Cause(..) => {
cur = None
Some(c)
}
Causes(msg~, err~, source~, loc~) => {
cur = Some(source)
Some(Cause(msg~, source=err, loc~))
}
}
}
})
}
///|
/// Returns an `Iter` that walks the error chain
#cfg(any(target="wasm-gc", target="native"))
pub fn Cause::errors(self : Cause) -> Iter[Cause] {
let mut cur : Cause? = Some(self)
Iter::new(fn() {
match cur {
None => None
Some(Cause(_) as c) => {
cur = None
Some(c)
}
Some(Causes(msg~, err~, source~, loc~)) => {
cur = Some(source)
Some(Cause(msg~, source=err, loc~))
}
}
})
}
///|
/// Call the function and wrap any error it raises
#inline
#callsite(autofill(loc))
pub fn[T] passby(
f : () -> T raise Error,
msg? : String = "",
loc~ : SourceLoc,
) -> T raise Cause {
f() catch {
e => by(e, msg~, loc~)
}
}