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:
parent
3cee5a9eb7
commit
5e8ab7856d
10 changed files with 62 additions and 44 deletions
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)?;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(())
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue