2
0
Fork 0
mirror of https://git.asonix.dog/asonix/pict-rs synced 2024-12-22 19:31:35 +00:00

Extract Status errors into command-specific errors

This commit is contained in:
asonix 2023-07-17 13:30:08 -05:00
parent 3cee5a9eb7
commit 5e8ab7856d
10 changed files with 62 additions and 44 deletions

View file

@ -40,8 +40,7 @@ pub(super) async fn check_reorient(
#[tracing::instrument(level = "trace", skip(input))] #[tracing::instrument(level = "trace", skip(input))]
async fn needs_reorienting(input: Bytes) -> Result<bool, ExifError> { async fn needs_reorienting(input: Bytes) -> Result<bool, ExifError> {
let process = let process = Process::run("exiftool", &["-n", "-Orientation", "-"])?;
Process::run("exiftool", &["-n", "-Orientation", "-"]).map_err(ExifError::Process)?;
let mut reader = process.bytes_read(input); let mut reader = process.bytes_read(input);
let mut buf = String::new(); let mut buf = String::new();

View file

@ -6,8 +6,8 @@ use std::{collections::HashSet, sync::OnceLock};
use crate::{ use crate::{
ffmpeg::FfMpegError, ffmpeg::FfMpegError,
formats::{ formats::{
AnimationFormat, ImageFormat, ImageInput, InputFile, InternalFormat, AnimationFormat, ImageFormat, ImageInput, InputFile, InternalFormat, InternalVideoFormat,
InternalVideoFormat, VideoFormat, VideoFormat,
}, },
process::Process, process::Process,
}; };
@ -220,8 +220,7 @@ where
"json", "json",
input_file_str, input_file_str,
], ],
) )?;
.map_err(FfMpegError::Process)?;
let mut output = Vec::new(); let mut output = Vec::new();
process process
@ -268,8 +267,7 @@ where
"compact=p=0:nk=1", "compact=p=0:nk=1",
input_file_str, input_file_str,
], ],
) )?;
.map_err(FfMpegError::Process)?;
let mut output = Vec::new(); let mut output = Vec::new();
process process
@ -298,8 +296,7 @@ async fn alpha_pixel_formats() -> Result<HashSet<String>, FfMpegError> {
"-print_format", "-print_format",
"json", "json",
], ],
) )?;
.map_err(FfMpegError::Process)?;
let mut output = Vec::new(); let mut output = Vec::new();
process process

View file

@ -137,8 +137,7 @@ where
let tmp_one = (f)(tmp_one).await?; let tmp_one = (f)(tmp_one).await?;
tmp_one.close().await.map_err(MagickError::CloseFile)?; tmp_one.close().await.map_err(MagickError::CloseFile)?;
let process = Process::run("magick", &["convert", "-ping", input_file_str, "INFO:"]) let process = Process::run("magick", &["convert", "-ping", input_file_str, "INFO:"])?;
.map_err(MagickError::Process)?;
let mut output = String::new(); let mut output = String::new();
process process
@ -192,8 +191,7 @@ where
let tmp_one = (f)(tmp_one).await?; let tmp_one = (f)(tmp_one).await?;
tmp_one.close().await.map_err(MagickError::CloseFile)?; tmp_one.close().await.map_err(MagickError::CloseFile)?;
let process = Process::run("magick", &["convert", "-ping", input_file_str, "JSON:"]) let process = Process::run("magick", &["convert", "-ping", input_file_str, "JSON:"])?;
.map_err(MagickError::Process)?;
let mut output = Vec::new(); let mut output = Vec::new();
process process

View file

@ -9,19 +9,30 @@ pub(crate) enum ExifError {
#[error("Error reading process output")] #[error("Error reading process output")]
Read(#[source] std::io::Error), Read(#[source] std::io::Error),
#[error("Invalid media file provided")]
CommandFailed(ProcessError),
}
impl From<ProcessError> for ExifError {
fn from(value: ProcessError) -> Self {
match value {
e @ ProcessError::Status(_, _) => Self::CommandFailed(e),
otherwise => Self::Process(otherwise),
}
}
} }
impl ExifError { impl ExifError {
pub(crate) fn is_client_error(&self) -> bool { pub(crate) fn is_client_error(&self) -> bool {
// if exiftool bails we probably have bad input // if exiftool bails we probably have bad input
matches!(self, Self::Process(ProcessError::Status(_))) matches!(self, Self::CommandFailed(_))
} }
} }
#[tracing::instrument(level = "trace", skip(input))] #[tracing::instrument(level = "trace", skip(input))]
pub(crate) async fn needs_reorienting(input: Bytes) -> Result<bool, ExifError> { pub(crate) async fn needs_reorienting(input: Bytes) -> Result<bool, ExifError> {
let process = let process = Process::run("exiftool", &["-n", "-Orientation", "-"])?;
Process::run("exiftool", &["-n", "-Orientation", "-"]).map_err(ExifError::Process)?;
let mut reader = process.bytes_read(input); let mut reader = process.bytes_read(input);
let mut buf = String::new(); let mut buf = String::new();
@ -35,8 +46,7 @@ pub(crate) async fn needs_reorienting(input: Bytes) -> Result<bool, ExifError> {
#[tracing::instrument(level = "trace", skip(input))] #[tracing::instrument(level = "trace", skip(input))]
pub(crate) fn clear_metadata_bytes_read(input: Bytes) -> Result<impl AsyncRead + Unpin, ExifError> { pub(crate) fn clear_metadata_bytes_read(input: Bytes) -> Result<impl AsyncRead + Unpin, ExifError> {
let process = let process = Process::run("exiftool", &["-all=", "-", "-out", "-"])?;
Process::run("exiftool", &["-all=", "-", "-out", "-"]).map_err(ExifError::Process)?;
Ok(process.bytes_read(input)) Ok(process.bytes_read(input))
} }

View file

@ -46,14 +46,26 @@ pub(crate) enum FfMpegError {
#[error("Error in store")] #[error("Error in store")]
Store(#[source] StoreError), Store(#[source] StoreError),
#[error("Invalid media file provided")]
CommandFailed(ProcessError),
#[error("Invalid file path")] #[error("Invalid file path")]
Path, Path,
} }
impl From<ProcessError> for FfMpegError {
fn from(value: ProcessError) -> Self {
match value {
e @ ProcessError::Status(_, _) => Self::CommandFailed(e),
otherwise => Self::Process(otherwise),
}
}
}
impl FfMpegError { impl FfMpegError {
pub(crate) fn is_client_error(&self) -> bool { pub(crate) fn is_client_error(&self) -> bool {
// Failing validation or ffmpeg bailing probably means bad input // Failing validation or ffmpeg bailing probably means bad input
matches!(self, Self::Process(ProcessError::Status(_))) matches!(self, Self::CommandFailed(_))
} }
pub(crate) fn is_not_found(&self) -> bool { pub(crate) fn is_not_found(&self) -> bool {
@ -143,10 +155,9 @@ pub(crate) async fn thumbnail<S: Store>(
format.as_ffmpeg_format(), format.as_ffmpeg_format(),
output_file_str, output_file_str,
], ],
) )?;
.map_err(FfMpegError::Process)?;
process.wait().await.map_err(FfMpegError::Process)?; process.wait().await?;
tokio::fs::remove_file(input_file) tokio::fs::remove_file(input_file)
.await .await
.map_err(FfMpegError::RemoveFile)?; .map_err(FfMpegError::RemoveFile)?;

View file

@ -37,6 +37,9 @@ pub(crate) enum MagickError {
#[error("Error in metadata discovery")] #[error("Error in metadata discovery")]
Discover(#[source] crate::discover::DiscoverError), Discover(#[source] crate::discover::DiscoverError),
#[error("Invalid media file provided")]
CommandFailed(ProcessError),
#[error("Command output is empty")] #[error("Command output is empty")]
Empty, Empty,
@ -44,10 +47,19 @@ pub(crate) enum MagickError {
Path, Path,
} }
impl From<ProcessError> for MagickError {
fn from(value: ProcessError) -> Self {
match value {
e @ ProcessError::Status(_, _) => Self::CommandFailed(e),
otherwise => Self::Process(otherwise),
}
}
}
impl MagickError { impl MagickError {
pub(crate) fn is_client_error(&self) -> bool { pub(crate) fn is_client_error(&self) -> bool {
// Failing validation or imagemagick bailing probably means bad input // Failing validation or imagemagick bailing probably means bad input
matches!(self, Self::Process(ProcessError::Status(_))) matches!(self, Self::CommandFailed(_))
} }
} }
@ -91,9 +103,7 @@ where
} }
args.push(&output_arg); args.push(&output_arg);
let reader = Process::run("magick", &args) let reader = Process::run("magick", &args)?.read();
.map_err(MagickError::Process)?
.read();
let clean_reader = crate::tmp_file::cleanup_tmpfile(reader, input_file); let clean_reader = crate::tmp_file::cleanup_tmpfile(reader, input_file);

View file

@ -53,8 +53,8 @@ pub(crate) enum ProcessError {
#[error("Reached process spawn limit")] #[error("Reached process spawn limit")]
LimitReached, LimitReached,
#[error("Failed with status {0}")] #[error("{0} Failed with {1}")]
Status(ExitStatus), Status(String, ExitStatus),
#[error("Unknown process error")] #[error("Unknown process error")]
Other(#[source] std::io::Error), Other(#[source] std::io::Error),
@ -98,7 +98,7 @@ impl Process {
match res { match res {
Ok(status) if status.success() => Ok(()), Ok(status) if status.success() => Ok(()),
Ok(status) => Err(ProcessError::Status(status)), Ok(status) => Err(ProcessError::Status(self.command, status)),
Err(e) => Err(ProcessError::Other(e)), Err(e) => Err(ProcessError::Other(e)),
} }
} }

View file

@ -5,8 +5,7 @@ use crate::{exiftool::ExifError, process::Process};
#[tracing::instrument(level = "trace", skip(input))] #[tracing::instrument(level = "trace", skip(input))]
pub(crate) fn clear_metadata_bytes_read(input: Bytes) -> Result<impl AsyncRead + Unpin, ExifError> { pub(crate) fn clear_metadata_bytes_read(input: Bytes) -> Result<impl AsyncRead + Unpin, ExifError> {
let process = let process = Process::run("exiftool", &["-all=", "-", "-out", "-"])?;
Process::run("exiftool", &["-all=", "-", "-out", "-"]).map_err(ExifError::Process)?;
Ok(process.bytes_read(input)) Ok(process.bytes_read(input))
} }

View file

@ -74,11 +74,9 @@ async fn transcode_files(
output_format.ffmpeg_format(), output_format.ffmpeg_format(),
output_path, output_path,
], ],
) )?
.map_err(FfMpegError::Process)?
.wait() .wait()
.await .await?;
.map_err(FfMpegError::Process)?;
} else { } else {
Process::run( Process::run(
"ffmpeg", "ffmpeg",
@ -101,11 +99,9 @@ async fn transcode_files(
output_format.ffmpeg_format(), output_format.ffmpeg_format(),
output_path, output_path,
], ],
) )?
.map_err(FfMpegError::Process)?
.wait() .wait()
.await .await?;
.map_err(FfMpegError::Process)?;
} }
Ok(()) Ok(())

View file

@ -67,14 +67,12 @@ async fn convert(
"-coalesce", "-coalesce",
&output_arg, &output_arg,
], ],
) )?
.map_err(MagickError::Process)?
} else { } else {
Process::run( Process::run(
"magick", "magick",
&["convert", "-strip", "-auto-orient", &input_arg, &output_arg], &["convert", "-strip", "-auto-orient", &input_arg, &output_arg],
) )?
.map_err(MagickError::Process)?
}; };
let reader = process.read(); let reader = process.read();