more descriptive errors
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing

This commit is contained in:
Jake Hillion 2022-04-08 20:54:31 +01:00
parent bb28c74833
commit 245bbfdf9d
4 changed files with 42 additions and 46 deletions

View File

@ -15,18 +15,12 @@ pub enum Error {
#[error("json: {0}")]
Json(#[from] serde_json::Error),
#[error("bad pipe specification: a pipe must have exactly one reader and one writer: {0}")]
BadPipe(String),
#[error("bad specification type: only .json files are supported")]
BadSpecType,
#[error("bad pipe trigger: this entrypoint is not triggered by a pipe")]
BadPipeTrigger,
#[error("too many pipes: a pipe must have one reader and one writer: {0}")]
TooManyPipes(String),
#[error("read only pipe: a pipe must have one reader and one writer: {0}")]
ReadOnlyPipe(String),
#[error("write only pipe: a pipe must have one reader and one writer: {0}")]
WriteOnlyPipe(String),
#[error("bad trigger argument: this entrypoint is not triggered by something with arguments")]
BadTriggerArgument,
}

View File

@ -79,45 +79,47 @@ pub fn run() -> Result<()> {
.spawn()
}
fn create_pipes(names: Vec<&str>) -> Result<HashMap<String, PipePair>> {
let mut pipes = HashMap::new();
for pipe in names {
info!("creating pipe pair `{}`", pipe);
pipes.insert(pipe.to_string(), PipePair::new(pipe)?);
}
Ok(pipes)
}
pub struct PipePair {
name: String,
read: Option<File>,
write: Option<File>,
}
impl PipePair {
fn take_read(&mut self) -> File {
self.read
.take()
.expect("read pipes should only be used once")
}
fn take_write(&mut self) -> File {
self.write
.take()
.expect("write pipes should only be used once")
}
}
fn create_pipes(names: Vec<&str>) -> Result<HashMap<String, PipePair>> {
let mut pipes = HashMap::new();
for pipe in names {
info!("creating pipe pair `{}`", pipe);
fn new(name: &str) -> Result<PipePair> {
let (read, write) = unistd::pipe2(OFlag::O_DIRECT).map_err(|e| Error::Nix {
msg: "pipe2",
src: e,
})?;
// safe to create files given the successful return of pipe(2)
pipes.insert(
pipe.to_string(),
PipePair {
read: Some(unsafe { File::from_raw_fd(read) }),
write: Some(unsafe { File::from_raw_fd(write) }),
},
);
Ok(PipePair {
name: name.to_string(),
read: Some(unsafe { File::from_raw_fd(read) }),
write: Some(unsafe { File::from_raw_fd(write) }),
})
}
Ok(pipes)
fn take_read(&mut self) -> Result<File> {
self.read
.take()
.ok_or_else(|| Error::BadPipe(self.name.to_string()))
}
fn take_write(&mut self) -> Result<File> {
self.write
.take()
.ok_or_else(|| Error::BadPipe(self.name.to_string()))
}
}

View File

@ -55,7 +55,7 @@ impl<'a> Spawner<'a> {
}
Trigger::Pipe(s) => {
let pipe = self.pipes.get_mut(s).unwrap().take_read();
let pipe = self.pipes.get_mut(s).unwrap().take_read().unwrap();
let binary = PathBuf::from(self.binary).canonicalize()?;
let mut builder = VoidBuilder::new();
@ -126,11 +126,11 @@ impl<'a> Spawner<'a> {
Arg::Pipe(p) => out.push(match p {
Pipe::Rx(s) => {
let pipe = self.pipes.get_mut(s).unwrap().take_read();
let pipe = self.pipes.get_mut(s).unwrap().take_read().unwrap();
CString::new(pipe.as_raw_fd().to_string()).unwrap()
}
Pipe::Tx(s) => {
let pipe = self.pipes.get_mut(s).unwrap().take_write();
let pipe = self.pipes.get_mut(s).unwrap().take_write().unwrap();
CString::new(pipe.as_raw_fd().to_string()).unwrap()
}
}),

View File

@ -122,25 +122,25 @@ impl Specification {
for pipe in read {
if !read_set.insert(pipe) {
return Err(Error::TooManyPipes(pipe.to_string()));
return Err(Error::BadPipe(pipe.to_string()));
}
}
let mut write_set = HashSet::with_capacity(write.len());
for pipe in write {
if !write_set.insert(pipe) {
return Err(Error::TooManyPipes(pipe.to_string()));
return Err(Error::BadPipe(pipe.to_string()));
}
}
for pipe in read_set {
if !write_set.remove(pipe) {
return Err(Error::ReadOnlyPipe(pipe.to_string()));
return Err(Error::BadPipe(pipe.to_string()));
}
}
if let Some(pipe) = write_set.into_iter().next() {
return Err(Error::WriteOnlyPipe(pipe.to_string()));
return Err(Error::BadPipe(pipe.to_string()));
}
// validate pipe trigger arguments make sense
@ -148,7 +148,7 @@ impl Specification {
if entrypoint.args.contains(&Arg::PipeTrigger) {
match entrypoint.trigger {
Trigger::Pipe(_) => {}
_ => return Err(Error::BadPipeTrigger),
_ => return Err(Error::BadTriggerArgument),
}
}
}