///|
/// Expected command failures that an error policy can present to the user.
///
/// Raise these from handlers, checks, or app middleware; the application's
/// `ErrorPolicy` turns them into user-facing responses. A permission guard
/// computed with `@util.channel_permissions` typically raises
/// `MissingPermission`:
///
/// ```mbt check
/// test "guard a handler with a permission requirement" {
/// fn require_send_messages(permissions : @model.Permissions) -> Unit raise {
/// let required = @model.Permissions::send_messages()
/// if !permissions.contains(required) {
/// raise @app.HandlerError::MissingPermission(required)
/// }
/// }
///
/// try require_send_messages(@model.Permissions::none()) catch {
/// @app.HandlerError::MissingPermission(_) => ()
/// other => raise other
/// } noraise {
/// _ => fail("expected MissingPermission")
/// }
/// }
/// ```
pub(all) suberror HandlerError {
UserMessage(message~ : String, ephemeral~ : Bool)
GuildOnly
DmOnly
CheckFailed
MissingPermission(@model.Permissions)
OnCooldown(retry_after_ms~ : Int64)
/// A submitted value the user can correct, such as an argument outside its
/// declared range. `message` is shown to the user; `name` identifies the
/// option when there is one.
InvalidInput(name~ : String?, message~ : String)
/// The interaction does not match what the app declared: typically a stale
/// command registration, an old component, or a payload missing data
/// Discord should have sent. `reason` is for logs and never shown to users.
Malformed(reason~ : String)
/// The handler chose a response Discord does not accept for this
/// interaction, such as updating the message of a modal a command opened.
/// It is an app bug, not a user error: `reason` is for logs, and the default
/// policy tells the user only that something went wrong.
UnsupportedResponse(reason~ : String)
/// Too many deferred interactions are already waiting for handler capacity
/// (`AppBuilder`'s `max_pending`). Raised before anything is acknowledged;
/// the default policy asks the user to try again.
Busy
} derive(Debug)
///|
/// Keep a `HandlerError` raised by user code as is, and classify any other
/// decode failure as a malformed interaction.
fn malformed_unless_handler_error(error : Error) -> HandlerError {
match error {
UserMessage(..) as error => error
GuildOnly => GuildOnly
DmOnly => DmOnly
CheckFailed => CheckFailed
MissingPermission(_) as error => error
OnCooldown(..) as error => error
InvalidInput(..) as error => error
Malformed(..) as error => error
UnsupportedResponse(..) as error => error
Busy => Busy
error => Malformed(reason=Repr(error).to_string())
}
}