use crate::{Port, VersionRequest};
use chrome_for_testing::{Platform, Version};
use std::{
fmt::{Display, Formatter},
path::PathBuf,
time::Duration,
};
use thiserror::Error;
use tokio::runtime::RuntimeFlavor;
pub type Result<T> = std::result::Result<T, rootcause::Report<ChromeForTestingManagerError>>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ChromeForTestingArtifact {
Chrome,
ChromeDriver,
}
impl Display for ChromeForTestingArtifact {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Chrome => f.write_str("chrome"),
Self::ChromeDriver => f.write_str("chromedriver"),
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum ChromeForTestingManagerError {
#[error("chromedriver requires a multi-threaded Tokio runtime; detected {runtime_flavor:?}")]
UnsupportedRuntime {
runtime_flavor: RuntimeFlavor,
},
#[error("unsupported chrome-for-testing platform")]
UnsupportedPlatform,
#[error("failed to determine cache directory; is $HOME set?")]
DetermineCacheDir,
#[error("failed to create cache directory {}", .cache_dir.display())]
CreateCacheDir {
cache_dir: PathBuf,
},
#[error("failed to remove cache directory {}", .cache_dir.display())]
RemoveCacheDir {
cache_dir: PathBuf,
},
#[error("failed to recreate cache directory {}", .cache_dir.display())]
RecreateCacheDir {
cache_dir: PathBuf,
},
#[error("failed to request versions for {version_request:?}")]
RequestVersions {
version_request: VersionRequest,
},
#[error("could not determine a version for {version_request:?}")]
NoMatchingVersion {
version_request: VersionRequest,
},
#[error("no chrome download for version {version} on {platform}")]
NoChromeDownload {
version: Version,
platform: Platform,
},
#[error("no chromedriver download for version {version} on {platform}")]
NoChromedriverDownload {
version: Version,
platform: Platform,
},
#[error("failed to create platform directory {}", .platform_dir.display())]
CreatePlatformDir {
platform_dir: PathBuf,
},
#[error("failed to download {artifact} from {url}")]
Download {
artifact: ChromeForTestingArtifact,
url: String,
},
#[error("failed to create {artifact} download file {}", .path.display())]
CreateDownloadFile {
artifact: ChromeForTestingArtifact,
path: PathBuf,
},
#[error("failed to write {artifact} download chunk")]
WriteDownloadFile {
artifact: ChromeForTestingArtifact,
},
#[error("failed to flush {artifact} download file")]
FlushDownloadFile {
artifact: ChromeForTestingArtifact,
},
#[error(
"{artifact} download timed out after {consecutive_stalls} consecutive stalls of {chunk_timeout:?}"
)]
DownloadStalled {
artifact: ChromeForTestingArtifact,
consecutive_stalls: u32,
chunk_timeout: Duration,
},
#[error("failed to open downloaded ZIP archive {}", .path.display())]
OpenDownloadedZip {
path: PathBuf,
},
#[error("downloaded file {} is not a valid ZIP archive", .path.display())]
InvalidZip {
path: PathBuf,
},
#[error(
"downloaded ZIP archive {} decompressed size {size} exceeds safety limit {max_size}",
.path.display()
)]
ZipTooLarge {
path: PathBuf,
size: u128,
max_size: u128,
},
#[error(
"failed to extract ZIP archive {} to {}",
.path.display(),
.unpack_dir.display()
)]
ExtractZip {
path: PathBuf,
unpack_dir: PathBuf,
},
#[error("failed to remove downloaded ZIP archive {}", .path.display())]
RemoveDownloadedZip {
path: PathBuf,
},
#[error("failed to spawn chromedriver process {}", .path.display())]
SpawnChromedriver {
path: PathBuf,
},
#[error("failed while waiting for chromedriver {} to start", .path.display())]
WaitForChromedriverStartup {
path: PathBuf,
},
#[error("failed to terminate chromedriver process on port {port}")]
TerminateChromedriver {
port: Port,
},
#[error(
"failed to prepare Chrome capabilities for {}",
.chrome_executable.display()
)]
PrepareChromeCapabilities {
chrome_executable: PathBuf,
},
#[error("failed to configure Chrome capabilities")]
ConfigureSessionCapabilities,
#[error("failed to start WebDriver session on port {port}")]
StartWebDriverSession {
port: Port,
},
#[error("session callback failed")]
RunSessionCallback,
#[error("failed to quit WebDriver session")]
QuitSession,
}