///|
/// Something the App or its executor handled on its own but an operator should
/// know about. Delivered to `AppBuilder::on_warn`; without a hook the App
/// prints it. `Show` renders a one-line message for every variant, so a hook
/// that only logs can call `to_string()`.
#non_exhaustive
pub(all) enum AppWarning {
/// The watchdog tried to defer a slow deferring route and the defer failed.
AutoDeferFailed(target~ : String, error~ : Error)
/// An immediate or raw route's response deadline passed before its handler
/// could start (usually while waiting for handler capacity), so the
/// interaction was not answered.
InteractionDropped(target~ : String)
/// A deferred interaction's token expired before its handler could start
/// (usually while waiting for handler capacity), so its handler never ran.
DeferredInteractionExpired(target~ : String)
/// The executor was stopping (its `HandlerIntake` closed) before the
/// handler could start, so its handler never ran.
InteractionDroppedWhileStopping(target~ : String)
/// An error policy tried to respond to a failure that has no interaction
/// (an event or a service). `summary` describes the discarded response.
ErrorResponseWithoutInteraction(summary~ : String)
/// An error policy tried to respond after the interaction's window closed.
ErrorResponseExpired(summary~ : String)
/// The default policy met `HandlerError::Malformed`; `reason` is for logs.
MalformedInteraction(origin~ : FailureOrigin, reason~ : String)
/// The default policy met an error it does not render for users.
UnhandledFailure(origin~ : FailureOrigin, error~ : Error)
/// The error policy itself raised.
ErrorPolicyFailed(error~ : Error)
/// An autocomplete handler returned more than Discord's 25 choices; the
/// first 25 were sent.
AutocompleteTruncated(
command_path~ : String,
option~ : String,
count~ : Int32
)
/// A handler registered directly on the framework raised.
HandlerFailed(target~ : String, error~ : Error)
/// `wait_for_component` ran on an executor without a gateway connection.
WaiterUnavailable
/// The executor could not process an interaction at all.
InteractionProcessingFailed(error~ : Error)
/// A warning raised by an executor about its own transport (for example the
/// gateway `Bot`), identified by `source`.
Executor(source~ : String, message~ : String)
/// `max_pending` deferred interactions already wait for a handler, so more
/// are refused with `HandlerError::Busy` until one starts. Reported once
/// per overload.
DeferredInteractionsRefused(max_pending~ : Int32)
/// The cooldown store stopped answering; `outage` is what commands with a
/// cooldown do until it answers again. Reported once per outage.
CooldownUnavailable(reason~ : String, outage~ : CooldownOutage)
} derive(Debug)
///|
/// The one-line message, as the default hook prints it.
pub extend AppWarning with Show::{to_string}
///|
pub impl Show for AppWarning with fn output(self, logger) {
match self {
AutoDeferFailed(target~, error~) =>
logger.write_string("automatic defer failed (\{target}): \{Repr(error)}")
InteractionDropped(target~) =>
logger.write_string(
"interaction dropped (\{target}): the response deadline passed before the handler could start",
)
DeferredInteractionExpired(target~) =>
logger.write_string(
"deferred interaction expired (\{target}): the interaction token expired before the handler could start",
)
InteractionDroppedWhileStopping(target~) =>
logger.write_string(
"interaction dropped (\{target}): the executor was stopping before the handler could start",
)
ErrorResponseWithoutInteraction(summary~) =>
logger.write_string(
"cannot respond to a non-interaction failure: \{summary}",
)
ErrorResponseExpired(summary~) =>
logger.write_string(
"cannot respond to an expired interaction: \{summary}",
)
MalformedInteraction(origin~, reason~) =>
logger.write_string("malformed interaction (\{Repr(origin)}): \{reason}")
UnhandledFailure(origin~, error~) =>
logger.write_string(
"unhandled app failure (\{Repr(origin)}): \{Repr(error)}",
)
ErrorPolicyFailed(error~) =>
logger.write_string("error policy failed: \{Repr(error)}")
AutocompleteTruncated(command_path~, option~, count~) =>
logger.write_string(
"autocomplete choices truncated for command path \{command_path}, option \{option}: \{count} choices exceeds the limit of 25",
)
HandlerFailed(target~, error~) =>
logger.write_string(
"framework handler failed (\{target}): \{Repr(error)}",
)
WaiterUnavailable =>
logger.write_string(
"component waiting is unavailable without a gateway connection",
)
InteractionProcessingFailed(error~) =>
logger.write_string("interaction processing failed: \{Repr(error)}")
Executor(message~, ..) => logger.write_string(message)
DeferredInteractionsRefused(max_pending~) =>
logger.write_string(
"\{max_pending} deferred interactions are waiting for a handler; refusing more as busy until one starts",
)
CooldownUnavailable(reason~, outage~) => {
let effect = match outage {
Allow => "commands run without cooldowns"
Refuse => "commands with a cooldown are refused"
}
logger.write_string(
"cooldown store unavailable (\{reason}): \{effect} until it answers again",
)
}
}
}