use std::io;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::time::Duration;
use thiserror::Error;
use crate::doctor::MissingTools;
use crate::scaffold::NewError;
#[derive(Debug, Error)]
pub enum CliError {
#[error("frame dev: {detail}")]
Dev {
detail: String,
},
#[error(transparent)]
New(#[from] NewError),
#[error(transparent)]
Git(#[from] crate::scaffold::GitError),
#[error(transparent)]
MissingTools(#[from] MissingTools),
#[error("{reason}")]
MissingChrome {
reason: String,
},
#[error(
"not inside a Frame application: no frame.toml in `{start}` or any parent directory; \
run this inside an application created by `frame new` (or create one: `frame new my_app`)"
)]
NotAnApplication {
start: PathBuf,
},
#[error("`{path}` is not a valid frame.toml")]
Config {
path: PathBuf,
#[source]
source: Box<frame_host::HostError>,
},
#[error("frame host failed")]
Host {
#[source]
source: Box<frame_host::HostError>,
},
#[error("`{command}` failed with {status}; its output above names the failure")]
CommandFailed {
command: String,
status: String,
},
#[error("`{command}` could not be started: {source}")]
CommandSpawn {
command: String,
#[source]
source: io::Error,
},
#[error(
"{changed} page source file(s) changed since the page was last compiled, and the page \
toolchain is not installed; run `npm --prefix page install` once (network), or run \
`frame check` or `frame test`, which install it for you"
)]
PageToolchainMissing {
changed: usize,
},
#[error("{operation} `{path}` failed: {source}")]
Io {
operation: &'static str,
path: PathBuf,
#[source]
source: io::Error,
},
#[error("reading the current directory failed: {source}")]
CurrentDir {
#[source]
source: io::Error,
},
#[error("starting frame's process supervisor failed: {source}")]
Runtime {
#[source]
source: io::Error,
},
#[error(
"cannot start the {role}: the port named by frame.toml `{key}` ({addr}) is unavailable \
({source}). {coherence}"
)]
PortUnavailable {
role: &'static str,
key: &'static str,
addr: SocketAddr,
coherence: &'static str,
#[source]
source: io::Error,
},
#[error(
"the application booted but `{bind}` never accepted a connection within {deadline:?}; \
its output above names what went wrong"
)]
NeverReady {
bind: String,
deadline: Duration,
},
#[error(
"the application did not exit within {deadline:?} of SIGTERM and was killed; \
this is a bug in the application's shutdown path"
)]
TeardownTimeout {
deadline: Duration,
},
#[error("{verb}: FAIL ({})", failed.join(", "))]
VerdictFailed {
verb: &'static str,
failed: Vec<String>,
},
#[error(
"frame doctor found {problems} problem(s); each line above carries its fix and install link"
)]
DoctorProblems {
problems: usize,
},
}