risingwave_common::error

Derive Macro Macro

#[derive(Macro)]
{
    // Attributes available to this derive:
    #[thiserror_ext]
    #[message]
}
Expand description

Generates macros for different variants of the error type to construct it or directly bail out.

§Inline formatting

It’s common to put a message string in the error variant. With this macro, one can directly format the message in the macro call, instead of calling [format!].

To mark a field as the message to be formatted, name it message or mark it with #[message]. The message field can be any type that implements From<String>.

§Example

#[derive(Debug, thiserror::Error, thiserror_ext::Macro)]
enum Error {
    #[error("internal error: {msg}")]
    Internal { #[message] msg: Box<str> },
}

// Equivalent to `Error::Internal { msg: format!(..).into() }`.
let _: Error = internal!("{} is a bad number", 42);

// Equivalent to `return Err(Error::Internal { msg: format!(..).into() }.into())`.
bail_internal!("{} is a bad number", 42);

§Extra fields

If there’re extra fields along with the message field, one can specify the values of them with field = value syntax before the message. The values can be any types that implement [Into] for the corresponding fields.

Fields can be omitted, in which case [Default::default()] will be used.

§Example

#[derive(Debug, thiserror::Error, thiserror_ext::Macro)]
#[error("not yet implemented: {message}")]
struct NotYetImplemented {
    issue: Option<i32>,
    pr: Option<i32>,
    message: String,
}

let _: Error = not_yet_implemented!(issue = 42, pr = 88, "foo");
let _: Error = not_yet_implemented!(issue = 42, "foo"); // pr = None
let _: Error = not_yet_implemented!(pr = 88, "foo");    // issue = None
let _: Error = not_yet_implemented!("foo");             // issue = None, pr = None

§Visibility

There’s a different rule set for the visibility of the macros. The macros generated by this proc-macro are marked with #[macro_export] only if the visibility of the error type is pub, otherwise they’re just re-exported with the same visibility as the error type and only work in the same crate.

There’re some extra configurations to help to better handle the visibility, specified in #[thiserror_ext(macro(..))]:

  • vis = ..: use a different visibility for the macro re-export.
  • mangle: mangle the macro names so that they don’t conflict with other macros with the same name in the crate root.
  • path = "crate::..": the path to the current module. When specified, types in the generated macros will use the qualified path like $crate::foo::bar::Error, enabling the callers to use the macros without importing the error type.

§New type

If a new type is specified with #[thiserror_ext(newtype(..))], the macros will generate the new type instead.

See the documentation of thiserror_ext::Box or thiserror_ext::Arc for more details.