2021-08-19 10:44:02 +02:00
|
|
|
//! Error types for critical, runtime, and specialised errors.
|
2018-09-08 13:51:44 +02:00
|
|
|
|
2021-10-09 07:41:45 +02:00
|
|
|
use std::{path::PathBuf};
|
2018-09-08 13:51:44 +02:00
|
|
|
|
2021-08-16 11:49:12 +02:00
|
|
|
use miette::Diagnostic;
|
2021-08-16 15:15:17 +02:00
|
|
|
use thiserror::Error;
|
2021-08-18 15:12:50 +02:00
|
|
|
use tokio::{
|
|
|
|
sync::{mpsc, watch},
|
|
|
|
task::JoinError,
|
|
|
|
};
|
2018-09-08 13:51:44 +02:00
|
|
|
|
2021-10-09 07:41:45 +02:00
|
|
|
use crate::{action, event::Event, fs::{self, Watcher}};
|
2019-01-26 02:45:08 +01:00
|
|
|
|
2021-08-16 11:49:12 +02:00
|
|
|
/// Errors which are not recoverable and stop watchexec execution.
|
|
|
|
#[derive(Debug, Diagnostic, Error)]
|
|
|
|
#[non_exhaustive]
|
|
|
|
pub enum CriticalError {
|
2021-08-22 16:32:08 +02:00
|
|
|
/// Pseudo-error used to signal a graceful exit.
|
|
|
|
#[error("this should never be printed (exit)")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::exit))]
|
|
|
|
Exit,
|
|
|
|
|
2021-10-09 07:38:37 +02:00
|
|
|
/// For custom critical errors.
|
|
|
|
///
|
|
|
|
/// This should be used for errors by external code which are not covered by the other error
|
|
|
|
/// types; watchexec-internal errors should never use this.
|
|
|
|
#[error("external(critical): {0}")]
|
|
|
|
#[diagnostic(code(watchexec::critical::external))]
|
|
|
|
External(#[from] Box<dyn std::error::Error + Send + Sync>),
|
|
|
|
|
2021-08-16 11:49:12 +02:00
|
|
|
/// A critical I/O error occurred.
|
|
|
|
#[error(transparent)]
|
|
|
|
#[diagnostic(code(watchexec::critical::io_error))]
|
|
|
|
IoError(#[from] std::io::Error),
|
2018-09-08 13:51:44 +02:00
|
|
|
|
2021-08-24 12:20:44 +02:00
|
|
|
/// Error received when a runtime error cannot be sent to the errors channel.
|
2021-08-16 11:49:12 +02:00
|
|
|
#[error("cannot send internal runtime error: {0}")]
|
|
|
|
#[diagnostic(code(watchexec::critical::error_channel_send))]
|
|
|
|
ErrorChannelSend(#[from] mpsc::error::SendError<RuntimeError>),
|
2021-08-18 15:12:50 +02:00
|
|
|
|
2021-08-24 12:20:44 +02:00
|
|
|
/// Error received when an event cannot be sent to the events channel.
|
|
|
|
#[error("cannot send event to internal channel: {0}")]
|
|
|
|
#[diagnostic(code(watchexec::critical::event_channel_send))]
|
|
|
|
EventChannelSend(#[from] mpsc::error::SendError<Event>),
|
|
|
|
|
2021-08-18 15:12:50 +02:00
|
|
|
/// Error received when joining the main watchexec task.
|
|
|
|
#[error("main task join: {0}")]
|
|
|
|
#[diagnostic(code(watchexec::critical::main_task_join))]
|
|
|
|
MainTaskJoin(#[source] JoinError),
|
2021-08-21 19:58:03 +02:00
|
|
|
|
|
|
|
/// Error received when a handler is missing on initialisation.
|
|
|
|
///
|
2021-08-22 16:32:08 +02:00
|
|
|
/// This is a **bug** and should be reported.
|
2021-08-21 19:58:03 +02:00
|
|
|
#[error("internal: missing handler on init")]
|
|
|
|
#[diagnostic(code(watchexec::critical::internal::missing_handler))]
|
|
|
|
MissingHandler,
|
2018-09-08 13:51:44 +02:00
|
|
|
}
|
|
|
|
|
2021-08-16 11:49:12 +02:00
|
|
|
/// Errors which _may_ be recoverable, transient, or only affect a part of the operation, and should
|
|
|
|
/// be reported to the user and/or acted upon programatically, but will not outright stop watchexec.
|
|
|
|
#[derive(Debug, Diagnostic, Error)]
|
|
|
|
#[non_exhaustive]
|
|
|
|
pub enum RuntimeError {
|
2021-08-22 16:32:08 +02:00
|
|
|
/// Pseudo-error used to signal a graceful exit.
|
|
|
|
#[error("this should never be printed (exit)")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::exit))]
|
|
|
|
Exit,
|
|
|
|
|
2021-10-09 07:38:37 +02:00
|
|
|
/// For custom runtime errors.
|
|
|
|
///
|
|
|
|
/// This should be used for errors by external code which are not covered by the other error
|
|
|
|
/// types; watchexec-internal errors should never use this.
|
|
|
|
#[error("external(runtime): {0}")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::external))]
|
|
|
|
External(#[from] Box<dyn std::error::Error + Send + Sync>),
|
|
|
|
|
2021-08-16 11:49:12 +02:00
|
|
|
/// Generic I/O error, with no additional context.
|
|
|
|
#[error(transparent)]
|
|
|
|
#[diagnostic(code(watchexec::runtime::io_error))]
|
|
|
|
IoError(#[from] std::io::Error),
|
2018-09-08 13:51:44 +02:00
|
|
|
|
2021-08-16 11:49:12 +02:00
|
|
|
/// Error received when creating a filesystem watcher fails.
|
|
|
|
#[error("{kind:?} watcher failed to instantiate: {err}")]
|
|
|
|
#[diagnostic(
|
|
|
|
code(watchexec::runtime::fs_watcher_error),
|
2021-08-16 15:15:17 +02:00
|
|
|
help("perhaps retry with the poll watcher")
|
2021-08-16 11:49:12 +02:00
|
|
|
)]
|
2021-08-16 15:15:17 +02:00
|
|
|
FsWatcherCreate {
|
|
|
|
kind: Watcher,
|
|
|
|
#[source]
|
|
|
|
err: notify::Error,
|
|
|
|
},
|
2019-01-26 02:45:08 +01:00
|
|
|
|
2021-08-16 11:49:12 +02:00
|
|
|
/// Error received when reading a filesystem event fails.
|
|
|
|
#[error("{kind:?} watcher received an event that we could not read: {err}")]
|
2021-08-16 15:15:17 +02:00
|
|
|
#[diagnostic(code(watchexec::runtime::fs_watcher_event))]
|
|
|
|
FsWatcherEvent {
|
|
|
|
kind: Watcher,
|
|
|
|
#[source]
|
|
|
|
err: notify::Error,
|
|
|
|
},
|
2021-04-30 17:27:17 +02:00
|
|
|
|
2021-08-16 11:49:12 +02:00
|
|
|
/// Error received when adding to the pathset for the filesystem watcher fails.
|
|
|
|
#[error("while adding {path:?} to the {kind:?} watcher: {err}")]
|
2021-08-16 15:15:17 +02:00
|
|
|
#[diagnostic(code(watchexec::runtime::fs_watcher_path_add))]
|
|
|
|
FsWatcherPathAdd {
|
|
|
|
path: PathBuf,
|
|
|
|
kind: Watcher,
|
|
|
|
#[source]
|
|
|
|
err: notify::Error,
|
|
|
|
},
|
2019-02-15 05:02:07 +01:00
|
|
|
|
2021-08-16 11:49:12 +02:00
|
|
|
/// Error received when removing from the pathset for the filesystem watcher fails.
|
|
|
|
#[error("while removing {path:?} from the {kind:?} watcher: {err}")]
|
2021-08-16 15:15:17 +02:00
|
|
|
#[diagnostic(code(watchexec::runtime::fs_watcher_path_remove))]
|
|
|
|
FsWatcherPathRemove {
|
|
|
|
path: PathBuf,
|
|
|
|
kind: Watcher,
|
|
|
|
#[source]
|
|
|
|
err: notify::Error,
|
|
|
|
},
|
2018-09-08 13:51:44 +02:00
|
|
|
|
2021-09-02 19:22:15 +02:00
|
|
|
/// Opaque internal error from a command supervisor.
|
|
|
|
#[error("internal: command supervisor: {0}")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::internal_supervisor))]
|
|
|
|
InternalSupervisor(String),
|
|
|
|
|
2021-08-16 11:49:12 +02:00
|
|
|
/// Error received when an event cannot be sent to the event channel.
|
|
|
|
#[error("cannot send event from {ctx}: {err}")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::event_channel_send))]
|
2021-08-16 15:15:17 +02:00
|
|
|
EventChannelSend {
|
2021-08-17 11:41:13 +02:00
|
|
|
ctx: &'static str,
|
|
|
|
#[source]
|
|
|
|
err: mpsc::error::SendError<Event>,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// Error received when an event cannot be sent to the event channel.
|
|
|
|
#[error("cannot send event from {ctx}: {err}")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::event_channel_try_send))]
|
|
|
|
EventChannelTrySend {
|
2021-08-16 15:15:17 +02:00
|
|
|
ctx: &'static str,
|
|
|
|
#[source]
|
|
|
|
err: mpsc::error::TrySendError<Event>,
|
|
|
|
},
|
2021-08-19 10:30:35 +02:00
|
|
|
|
2021-08-20 18:43:15 +02:00
|
|
|
/// Error received when a [`Handler`][crate::handler::Handler] errors.
|
2021-08-19 10:30:35 +02:00
|
|
|
///
|
|
|
|
/// The error is completely opaque, having been flattened into a string at the error point.
|
|
|
|
#[error("handler error while {ctx}: {err}")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::handler))]
|
|
|
|
Handler { ctx: &'static str, err: String },
|
2021-08-22 14:28:20 +02:00
|
|
|
|
2021-08-24 18:41:14 +02:00
|
|
|
/// Error received when a [`Handler`][crate::handler::Handler] which has been passed a lock has kept that lock open after the handler has completed.
|
|
|
|
#[error("{0} handler returned while holding a lock alive")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::handler_lock_held))]
|
|
|
|
HandlerLockHeld(&'static str),
|
|
|
|
|
2021-08-22 14:28:20 +02:00
|
|
|
/// Error received when operating on a process.
|
|
|
|
#[error("when operating on process: {0}")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::process))]
|
|
|
|
Process(#[source] std::io::Error),
|
|
|
|
|
2021-08-24 18:41:14 +02:00
|
|
|
/// Error received when a process did not start correctly, or finished before we could even tell.
|
|
|
|
#[error("process was dead on arrival")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::process_doa))]
|
|
|
|
ProcessDeadOnArrival,
|
|
|
|
|
2021-08-22 14:28:20 +02:00
|
|
|
/// Error received when clearing the screen.
|
|
|
|
#[error("clear screen: {0}")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::clearscreen))]
|
|
|
|
Clearscreen(#[from] clearscreen::Error),
|
2021-09-14 10:09:57 +02:00
|
|
|
|
2021-10-09 07:41:45 +02:00
|
|
|
/// Error emitted by a [`Filterer`](crate::filter::Filterer).
|
|
|
|
///
|
|
|
|
/// With built-in filterers this will be a dynbox of
|
|
|
|
/// [`TaggedFiltererError`](crate::filter::TaggedFiltererError) or TODO, but it is possible to
|
|
|
|
/// use a custom filterer which emits a different error type.
|
|
|
|
#[error("{kind} filterer: {err}")]
|
|
|
|
#[diagnostic(code(watchexec::runtime::filterer))]
|
|
|
|
Filterer {
|
|
|
|
kind: &'static str,
|
2021-09-28 11:23:23 +02:00
|
|
|
|
|
|
|
#[source]
|
2021-10-09 07:41:45 +02:00
|
|
|
err: Box<dyn std::error::Error + Send + Sync>,
|
|
|
|
// FIXME: can we have dyn Diagnostic here or downcast it somehow?
|
2021-09-28 11:23:23 +02:00
|
|
|
},
|
2021-08-19 10:30:35 +02:00
|
|
|
}
|
|
|
|
|
2021-08-18 15:12:50 +02:00
|
|
|
/// Errors occurring from reconfigs.
|
|
|
|
#[derive(Debug, Diagnostic, Error)]
|
|
|
|
#[non_exhaustive]
|
|
|
|
pub enum ReconfigError {
|
2021-08-20 18:43:55 +02:00
|
|
|
/// Error received when the action processor cannot be updated.
|
|
|
|
#[error("reconfig: action watch: {0}")]
|
|
|
|
#[diagnostic(code(watchexec::reconfig::action_watch))]
|
|
|
|
ActionWatch(#[from] watch::error::SendError<action::WorkingData>),
|
|
|
|
|
|
|
|
/// Error received when the fs event source cannot be updated.
|
2021-08-18 15:12:50 +02:00
|
|
|
#[error("reconfig: fs watch: {0}")]
|
|
|
|
#[diagnostic(code(watchexec::reconfig::fs_watch))]
|
|
|
|
FsWatch(#[from] watch::error::SendError<fs::WorkingData>),
|
|
|
|
}
|