Two years ago I started the cex project to support checked exceptions in Rust. After eating my own dog food, I'd like to share some thoughts - with little code and more like an essay.
Checked exceptions provide code-as-documentation
#[cex] pub fn foo() -> Result!( () throws Bar, Baz );
The function signature indicates that foo()
may produce Bar
error and Baz
error. Without checked exceptions, this information can only be found in foo()
's API document, or by checking foo()
's implementation. Bar
and Baz
should not be considered as "internal details" if they appeared in API document.
Checked exceptions are similar to "a big enum as the crate error type"
The big enum way may be regarded as "a summarizing error type per crate".
-
The same: both provide concrete error types.
-
The difference: checked exceptions provide precise error types for each function, while
Result<T, TheBigEnum>
can be aliased asResult<T>
withpub type Result<T, E=TheBigEnum> = Result<T,E>;
.
General vs specific
Various errors may occur during execution of a function.
-
If regarded as errors in different stages of the function's computation, they shoud be organized as variants of a whole enum which is the function's Error type. We may call it error-type-per-function strategy. These error types are most specific.
-
If regarded as independent errors which are general enough to deal with and specific enough to report, they can be organized as checked exceptions. Logging could be enabled to specify the location where error occurred.
cex vs anyhow
-
The same: both provide convenient mechanisms for propagating errors and attaching context.
-
The difference: cex requires extra annotations of error types, but does not require trait bounds
std::error::Error
,Send
andSync
.
Checked exceptions are not necessarily infectious
Library users can choose whether or not to use checked exceptions even library author has utilized checked exceptions in library API.
-
Library author could provide "a big enum as the crate error", not for library API, but for library users' functions, the errors of which are all from the library API.
-
Library author could
impl std::error::Error for
each error thusimpl std::error::Error for
each checked exceptions. Library users can useBox<dyn std::error::Error>
as the error type of their own functions.