use std::path::{Path, PathBuf};
use std::fs;
use std::env;
fn relative_to_current<P: AsRef<Path>>(original_path: P) -> PathBuf {
let mut result = PathBuf::new();
let current = if let Ok(curr) = env::current_dir(){
curr
} else {
return original_path.as_ref().to_path_buf();
};
let path = if let Ok(path) = fs::canonicalize(&original_path) {
path
} else {
return original_path.as_ref().to_path_buf();
};
let mut current_iter = current.iter();
for segment in path.iter() {
if let Some(current_segment) = current_iter.next() {
if segment != current_segment {
return original_path.as_ref().to_path_buf();
}
} else {
result.push(segment);
}
}
result
}
error_chain! {
foreign_links {
Io(::std::io::Error);
ParseInt(::std::num::ParseIntError);
AddrParse(::std::net::AddrParseError);
Json(::serde_json::Error);
Nix(::nix::Error);
}
errors {
HexInvalidChar(chr: char) {
description("invalid char in hex"),
display("invalid char in hex: {}", chr),
}
HexInvalidLength {
description("odd length for hex string"),
display("odd length for hex string"),
}
TimeStringInvalid(string: String) {
description("invalid time string"),
display("invalid time string: {}", string),
}
TimeStringInvalidChar(chr: char) {
description("time string contains an invalid char"),
display("the char '{}' isn't allowed in time strings", chr),
}
TimeStringExpectedNumber(pos: usize) {
description("expected a number in the time string"),
display("expected a number in position {}", pos),
}
NotBehindProxy {
description("not behind enough proxies"),
display("not behind enough proxies"),
}
WrongRequestKind {
description("wrong request kind"),
display("wrong request kind"),
}
RateLimitConfigTooManySlashes {
description("too many slashes present"),
display("too many slashes present"),
}
ProviderNotFound(name: String) {
description("provider not found"),
display("unknown provider: {}", name),
}
ProviderGitHubInvalidEventName(name: String) {
description("invalid GitHub event name"),
display("invalid GitHub event name: {}", name),
}
ProviderGitLabInvalidEventName(name: String) {
description("invalid GitLab event name"),
display("invalid GitLab event name: {}", name),
}
BrokenChannel {
description("an internal communication channel is broken"),
display("an internal communication channel is broken"),
}
PoisonedLock {
description("an internal lock is poisoned"),
display("an internal lock is poisoned"),
}
BoxedError(boxed: Box<::std::error::Error + Send + Sync>) {
description("generic error"),
display("{}", boxed),
}
ScriptExecutionFailed(name: String) {
description("script execution failed"),
display("execution of the '{}' script failed", name),
}
ScriptParsingError(file: String, line: u32) {
description("script parsing error"),
display(
"parsing of the script '{}' failed (at line {})",
relative_to_current(file).to_string_lossy(), line,
),
}
RateLimitConfigError(string: String) {
description("error while parsing the rate limit config"),
display("error while parsing rate limit config '{}'", string),
}
}
}
impl Error {
pub fn pretty_print(&self) {
println!("Error: {}", self);
for chain in self.iter().skip(1) {
println!(" caused by: {}", chain);
}
}
}
impl<T> From<::std::sync::mpsc::SendError<T>> for Error {
fn from(_: ::std::sync::mpsc::SendError<T>) -> Error {
ErrorKind::BrokenChannel.into()
}
}
impl From<::std::sync::mpsc::RecvError> for Error {
fn from(_: ::std::sync::mpsc::RecvError) -> Error {
ErrorKind::BrokenChannel.into()
}
}
impl<T> From<::std::sync::PoisonError<T>> for Error {
fn from(_: ::std::sync::PoisonError<T>) -> Error {
ErrorKind::PoisonedLock.into()
}
}
impl From<Box<::std::error::Error + Send + Sync>> for Error {
fn from(err: Box<::std::error::Error + Send + Sync>) -> Error {
ErrorKind::BoxedError(err).into()
}
}