Add graceful exit support
This commit is contained in:
parent
f4a8a9fc6a
commit
17b09d8798
|
@ -105,6 +105,9 @@ pub enum Outcome {
|
|||
/// Clear the screen.
|
||||
Clear,
|
||||
|
||||
/// Exit watchexec.
|
||||
Exit,
|
||||
|
||||
/// When command is running, do the first, otherwise the second.
|
||||
IfRunning(Box<Outcome>, Box<Outcome>),
|
||||
|
||||
|
@ -224,6 +227,9 @@ async fn apply_outcome(
|
|||
) -> Result<(), RuntimeError> {
|
||||
match (process.as_mut(), outcome) {
|
||||
(_, Outcome::DoNothing) => {}
|
||||
(_, Outcome::Exit) => {
|
||||
return Err(RuntimeError::Exit);
|
||||
}
|
||||
(Some(p), Outcome::Stop) => {
|
||||
p.kill().await?;
|
||||
p.wait().await?;
|
||||
|
|
|
@ -19,6 +19,11 @@ use crate::{
|
|||
#[derive(Debug, Diagnostic, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum CriticalError {
|
||||
/// Pseudo-error used to signal a graceful exit.
|
||||
#[error("this should never be printed (exit)")]
|
||||
#[diagnostic(code(watchexec::runtime::exit))]
|
||||
Exit,
|
||||
|
||||
/// A critical I/O error occurred.
|
||||
#[error(transparent)]
|
||||
#[diagnostic(code(watchexec::critical::io_error))]
|
||||
|
@ -36,7 +41,7 @@ pub enum CriticalError {
|
|||
|
||||
/// Error received when a handler is missing on initialisation.
|
||||
///
|
||||
/// This is a critical bug and unlikely to be recoverable in any way.
|
||||
/// This is a **bug** and should be reported.
|
||||
#[error("internal: missing handler on init")]
|
||||
#[diagnostic(code(watchexec::critical::internal::missing_handler))]
|
||||
MissingHandler,
|
||||
|
@ -47,6 +52,11 @@ pub enum CriticalError {
|
|||
#[derive(Debug, Diagnostic, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum RuntimeError {
|
||||
/// Pseudo-error used to signal a graceful exit.
|
||||
#[error("this should never be printed (exit)")]
|
||||
#[diagnostic(code(watchexec::runtime::exit))]
|
||||
Exit,
|
||||
|
||||
/// Generic I/O error, with no additional context.
|
||||
#[error(transparent)]
|
||||
#[diagnostic(code(watchexec::runtime::io_error))]
|
||||
|
|
|
@ -77,7 +77,10 @@ impl Watchexec {
|
|||
|
||||
let error_hook = subtask!(error_hook, error_hook(er_r, eh));
|
||||
|
||||
try_join!(action, error_hook, fs, signal).map(drop)
|
||||
try_join!(action, error_hook, fs, signal).map(drop).or_else(|e| if matches!(e, CriticalError::Exit) {
|
||||
trace!("got graceful exit request via critical error, erasing the error");
|
||||
Ok(())
|
||||
} else { Err(e) })
|
||||
});
|
||||
|
||||
trace!("done with setup");
|
||||
|
@ -126,6 +129,11 @@ async fn error_hook(
|
|||
mut handler: Box<dyn Handler<RuntimeError> + Send>,
|
||||
) -> Result<(), CriticalError> {
|
||||
while let Some(err) = errors.recv().await {
|
||||
if matches!(err, RuntimeError::Exit) {
|
||||
trace!("got graceful exit request via runtime error, upgrading to crit");
|
||||
return Err(CriticalError::Exit);
|
||||
}
|
||||
|
||||
error!(%err, "runtime error");
|
||||
if let Err(err) = handler.handle(err) {
|
||||
error!(%err, "error while handling error");
|
||||
|
|
Loading…
Reference in New Issue