diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2019-03-19 12:18:05 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-19 12:18:05 -0400 |
commit | fa3c35301aa44975776b96c85f200de8eb500c22 (patch) | |
tree | 76f8d5e6f42e1c306a40efd0b80dce18528952f4 /cli/errors.rs | |
parent | c7d81fa9ff495986675c05e52e13acc9ffc85372 (diff) |
Rename //src/ to //cli/ (#1962)
To better distinguish the deno_core crate from the executable deno,
which will now be called "the cli" internally.
Diffstat (limited to 'cli/errors.rs')
-rw-r--r-- | cli/errors.rs | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/cli/errors.rs b/cli/errors.rs new file mode 100644 index 000000000..65118d070 --- /dev/null +++ b/cli/errors.rs @@ -0,0 +1,207 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use crate::js_errors::JSErrorColor; +pub use crate::msg::ErrorKind; +use crate::resolve_addr::ResolveAddrError; +use deno_core::JSError; +use hyper; +use std; +use std::fmt; +use std::io; +use url; + +pub type DenoResult<T> = std::result::Result<T, DenoError>; + +#[derive(Debug)] +pub struct DenoError { + repr: Repr, +} + +#[derive(Debug)] +enum Repr { + Simple(ErrorKind, String), + IoErr(io::Error), + UrlErr(url::ParseError), + HyperErr(hyper::Error), +} + +pub fn new(kind: ErrorKind, msg: String) -> DenoError { + DenoError { + repr: Repr::Simple(kind, msg), + } +} + +impl DenoError { + pub fn kind(&self) -> ErrorKind { + match self.repr { + Repr::Simple(kind, ref _msg) => kind, + // Repr::Simple(kind) => kind, + Repr::IoErr(ref err) => { + use std::io::ErrorKind::*; + match err.kind() { + NotFound => ErrorKind::NotFound, + PermissionDenied => ErrorKind::PermissionDenied, + ConnectionRefused => ErrorKind::ConnectionRefused, + ConnectionReset => ErrorKind::ConnectionReset, + ConnectionAborted => ErrorKind::ConnectionAborted, + NotConnected => ErrorKind::NotConnected, + AddrInUse => ErrorKind::AddrInUse, + AddrNotAvailable => ErrorKind::AddrNotAvailable, + BrokenPipe => ErrorKind::BrokenPipe, + AlreadyExists => ErrorKind::AlreadyExists, + WouldBlock => ErrorKind::WouldBlock, + InvalidInput => ErrorKind::InvalidInput, + InvalidData => ErrorKind::InvalidData, + TimedOut => ErrorKind::TimedOut, + Interrupted => ErrorKind::Interrupted, + WriteZero => ErrorKind::WriteZero, + Other => ErrorKind::Other, + UnexpectedEof => ErrorKind::UnexpectedEof, + _ => unreachable!(), + } + } + Repr::UrlErr(ref err) => { + use url::ParseError::*; + match err { + EmptyHost => ErrorKind::EmptyHost, + IdnaError => ErrorKind::IdnaError, + InvalidPort => ErrorKind::InvalidPort, + InvalidIpv4Address => ErrorKind::InvalidIpv4Address, + InvalidIpv6Address => ErrorKind::InvalidIpv6Address, + InvalidDomainCharacter => ErrorKind::InvalidDomainCharacter, + RelativeUrlWithoutBase => ErrorKind::RelativeUrlWithoutBase, + RelativeUrlWithCannotBeABaseBase => { + ErrorKind::RelativeUrlWithCannotBeABaseBase + } + SetHostOnCannotBeABaseUrl => ErrorKind::SetHostOnCannotBeABaseUrl, + Overflow => ErrorKind::Overflow, + } + } + Repr::HyperErr(ref err) => { + // For some reason hyper::errors::Kind is private. + if err.is_parse() { + ErrorKind::HttpParse + } else if err.is_user() { + ErrorKind::HttpUser + } else if err.is_canceled() { + ErrorKind::HttpCanceled + } else if err.is_closed() { + ErrorKind::HttpClosed + } else { + ErrorKind::HttpOther + } + } + } + } +} + +impl fmt::Display for DenoError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.repr { + Repr::Simple(_kind, ref err_str) => f.pad(err_str), + Repr::IoErr(ref err) => err.fmt(f), + Repr::UrlErr(ref err) => err.fmt(f), + Repr::HyperErr(ref err) => err.fmt(f), + } + } +} + +impl std::error::Error for DenoError { + fn description(&self) -> &str { + match self.repr { + Repr::Simple(_kind, ref msg) => msg.as_str(), + Repr::IoErr(ref err) => err.description(), + Repr::UrlErr(ref err) => err.description(), + Repr::HyperErr(ref err) => err.description(), + } + } + + fn cause(&self) -> Option<&dyn std::error::Error> { + match self.repr { + Repr::Simple(_kind, ref _msg) => None, + Repr::IoErr(ref err) => Some(err), + Repr::UrlErr(ref err) => Some(err), + Repr::HyperErr(ref err) => Some(err), + } + } +} + +impl From<io::Error> for DenoError { + #[inline] + fn from(err: io::Error) -> Self { + Self { + repr: Repr::IoErr(err), + } + } +} + +impl From<url::ParseError> for DenoError { + #[inline] + fn from(err: url::ParseError) -> Self { + Self { + repr: Repr::UrlErr(err), + } + } +} + +impl From<hyper::Error> for DenoError { + #[inline] + fn from(err: hyper::Error) -> Self { + Self { + repr: Repr::HyperErr(err), + } + } +} + +impl From<ResolveAddrError> for DenoError { + fn from(e: ResolveAddrError) -> Self { + match e { + ResolveAddrError::Syntax => Self { + repr: Repr::Simple( + ErrorKind::InvalidInput, + "invalid address syntax".to_string(), + ), + }, + ResolveAddrError::Resolution(io_err) => Self { + repr: Repr::IoErr(io_err), + }, + } + } +} + +pub fn bad_resource() -> DenoError { + new(ErrorKind::BadResource, String::from("bad resource id")) +} + +pub fn permission_denied() -> DenoError { + new( + ErrorKind::PermissionDenied, + String::from("permission denied"), + ) +} + +#[derive(Debug)] +pub enum RustOrJsError { + Rust(DenoError), + Js(JSError), +} + +impl From<DenoError> for RustOrJsError { + fn from(e: DenoError) -> Self { + RustOrJsError::Rust(e) + } +} + +impl From<JSError> for RustOrJsError { + fn from(e: JSError) -> Self { + RustOrJsError::Js(e) + } +} + +impl fmt::Display for RustOrJsError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + RustOrJsError::Rust(e) => e.fmt(f), + RustOrJsError::Js(e) => JSErrorColor(e).fmt(f), + } + } +} |