Skip to content

Commit

Permalink
use strings for ErrorKind
Browse files Browse the repository at this point in the history
  • Loading branch information
afinch7 committed Sep 5, 2019
1 parent 50bde53 commit 4b3f6d9
Show file tree
Hide file tree
Showing 37 changed files with 487 additions and 213 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
members = [
"bundle_util",
"cli",
"core",
"tools/hyper_hello",
"deno_typescript",
"cli_snapshots",
"core",
"deno_typescript",
"dispatch_json",
"dispatch_json/bundle",
"ops/fs",
Expand Down
24 changes: 24 additions & 0 deletions cli/deno_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub use crate::msg::ErrorKind;
use deno::AnyError;
use deno::ErrBox;
use deno::ModuleResolutionError;
use deno_dispatch_json::GetErrorKind as JsonGetErrorKind;
use http::uri;
use hyper;
use rustyline::error::ReadlineError;
Expand Down Expand Up @@ -274,6 +275,29 @@ impl GetErrorKind for dyn AnyError {
}
}

#[derive(Debug)]
pub struct CliOpError(ErrBox);

impl fmt::Display for CliOpError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}

impl Error for CliOpError {}

impl From<ErrBox> for CliOpError {
fn from(e: ErrBox) -> Self {
Self(e)
}
}

impl JsonGetErrorKind for CliOpError {
fn kind(&self) -> &str {
crate::msg::error_kind_str(GetErrorKind::kind(self.0.as_ref()))
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
57 changes: 57 additions & 0 deletions cli/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,63 @@ pub enum ErrorKind {
JSError = 50,
}

pub fn error_kind_str(e: ErrorKind) -> &'static str {
use ErrorKind::*;
match e {
NoError => "NoError",
NotFound => "NotFound",
PermissionDenied => "PermissionDenied",
ConnectionRefused => "ConnectionRefused",
ConnectionReset => "ConnectionReset",
ConnectionAborted => "ConnectionAborted",
NotConnected => "NotConnected",
AddrInUse => "AddrInUse",
AddrNotAvailable => "AddrNotAvailable",
BrokenPipe => "BrokenPipe",
AlreadyExists => "AlreadyExists",
WouldBlock => "WouldBlock",
InvalidInput => "InvalidInput",
InvalidData => "InvalidData",
TimedOut => "TimedOut",
Interrupted => "Interrupted",
WriteZero => "WriteZero",
Other => "Other",
UnexpectedEof => "UnexpectedEof",
BadResource => "BadResource",
CommandFailed => "CommandFailed",
EmptyHost => "EmptyHost",
IdnaError => "IdnaError",
InvalidPort => "InvalidPort",
InvalidIpv4Address => "InvalidIpv4Address",
InvalidIpv6Address => "InvalidIpv6Address",
InvalidDomainCharacter => "InvalidDomainCharacter",
RelativeUrlWithoutBase => "RelativeUrlWithoutBase",
RelativeUrlWithCannotBeABaseBase => "RelativeUrlWithCannotBeABaseBase",
SetHostOnCannotBeABaseUrl => "SetHostOnCannotBeABaseUrl",
Overflow => "Overflow",
HttpUser => "HttpUser",
HttpClosed => "HttpClosed",
HttpCanceled => "HttpCanceled",
HttpParse => "HttpParse",
HttpOther => "HttpOther",
TooLarge => "TooLarge",
InvalidUri => "InvalidUri",
InvalidSeekMode => "InvalidSeekMode",
OpNotAvailable => "OpNotAvailable",
WorkerInitFailed => "WorkerInitFailed",
UnixError => "UnixError",
NoAsyncSupport => "NoAsyncSupport",
NoSyncSupport => "NoSyncSupport",
ImportMapError => "ImportMapError",
InvalidPath => "InvalidPath",
ImportPrefixMissing => "ImportPrefixMissing",
UnsupportedFetchScheme => "UnsupportedFetchScheme",
TooManyRedirects => "TooManyRedirects",
Diagnostic => "Diagnostic",
JSError => "JSError",
}
}

// Warning! The values in this enum are duplicated in js/compiler.ts
// Update carefully!
#[allow(non_camel_case_types)]
Expand Down
2 changes: 1 addition & 1 deletion cli/ops/dispatch_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn json_err(err: ErrBox) -> Value {
use crate::deno_error::GetErrorKind;
json!({
"message": err.to_string(),
"kind": err.kind() as u32,
"kind": crate::msg::error_kind_str(err.kind()),
})
}

Expand Down
3 changes: 2 additions & 1 deletion cli/ops/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ impl DenoOpDispatcher for OpOpen {
wrap_json_op(
move |args, _zero_copy| {
let args: OpenArgs = serde_json::from_value(args)?;
let (filename, filename_) = deno_fs::resolve_from_cwd(&args.filename)?;
let (filename, filename_) = deno_fs::resolve_from_cwd(&args.filename)
.map_err(|e| ErrBox::from(e))?;
let mode = args.mode.as_ref();

let mut open_options = tokio::fs::OpenOptions::new();
Expand Down
14 changes: 12 additions & 2 deletions cli/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,18 @@ pub fn setup_dispatcher_registry(state: ThreadSafeState) -> Arc<OpDisReg> {
let state_ = state.clone();
let state__ = state.clone();
let fs_state = fs::TSFsOpsState::new(
move |filename| state_.check_read(filename),
move |filename| state__.check_write(filename),
move |filename| {
state_
.check_read(filename)
.map_err(crate::deno_error::CliOpError::from)
.map_err(deno_dispatch_json::JsonErrBox::from)
},
move |filename| {
state__
.check_write(filename)
.map_err(crate::deno_error::CliOpError::from)
.map_err(deno_dispatch_json::JsonErrBox::from)
},
);

// Fs
Expand Down
99 changes: 99 additions & 0 deletions dispatch_json/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use deno::AnyError as DenoAnyError;
use std::any::{Any, TypeId};
use std::convert::From;
use std::error::Error;
use std::fmt;
use std::ops::Deref;

pub trait GetErrorKind: Error {
fn kind(&self) -> &str;
}

impl GetErrorKind for dyn DenoAnyError {
fn kind(&self) -> &str {
"UnkownErrorKind"
}
}

impl GetErrorKind for serde_json::error::Error {
fn kind(&self) -> &str {
use serde_json::error::*;
match self.classify() {
Category::Io => "InvalidInput",
Category::Syntax => "InvalidInput",
Category::Data => "InvalidData",
Category::Eof => "UnexpectedEof",
}
}
}

// The Send and Sync traits are required because deno is multithreaded and we
// need to beable to handle errors across threads.
pub trait JsonAnyError:
Any + GetErrorKind + Error + Send + Sync + 'static
{
}
impl<T> JsonAnyError for T where
T: Any + GetErrorKind + Error + Send + Sync + Sized + 'static
{
}

#[derive(Debug)]
pub struct JsonErrBox(Box<dyn JsonAnyError>);

impl dyn JsonAnyError {
pub fn downcast_ref<T: JsonAnyError>(&self) -> Option<&T> {
if Any::type_id(self) == TypeId::of::<T>() {
let target = self as *const Self as *const T;
let target = unsafe { &*target };
Some(target)
} else {
None
}
}
}

impl JsonErrBox {
pub fn downcast<T: JsonAnyError>(self) -> Result<T, Self> {
if Any::type_id(&*self.0) == TypeId::of::<T>() {
let target = Box::into_raw(self.0) as *mut T;
let target = unsafe { Box::from_raw(target) };
Ok(*target)
} else {
Err(self)
}
}
}

impl AsRef<dyn JsonAnyError> for JsonErrBox {
fn as_ref(&self) -> &dyn JsonAnyError {
self.0.as_ref()
}
}

impl Deref for JsonErrBox {
type Target = Box<dyn JsonAnyError>;
fn deref(&self) -> &Self::Target {
&self.0
}
}

impl<T: JsonAnyError> From<T> for JsonErrBox {
fn from(error: T) -> Self {
Self(Box::new(error))
}
}

impl From<Box<dyn JsonAnyError>> for JsonErrBox {
fn from(boxed: Box<dyn JsonAnyError>) -> Self {
Self(boxed)
}
}

impl fmt::Display for JsonErrBox {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}

impl Error for JsonErrBox {}
22 changes: 13 additions & 9 deletions dispatch_json/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,33 @@
#[macro_use]
extern crate log;

mod error;

pub use crate::error::*;
use deno::*;
use futures::Future;
use futures::Poll;
pub use serde_derive::Deserialize;
use serde_json::json;
pub use serde_json::Value;

pub type AsyncJsonOp = Box<dyn Future<Item = Value, Error = ErrBox> + Send>;
pub type AsyncJsonOp = Box<dyn Future<Item = Value, Error = JsonErrBox> + Send>;

pub enum JsonOp {
Sync(Value),
Async(AsyncJsonOp),
}

fn json_err(err: ErrBox) -> Value {
fn json_err(err: JsonErrBox) -> Value {
json!({
"message": err.to_string(),
"kind": err.kind(),
})
}

fn serialize_result(
promise_id: Option<u64>,
result: Result<Value, ErrBox>,
result: Result<Value, JsonErrBox>,
) -> Buf {
let value = match result {
Ok(v) => json!({ "ok": v, "promiseId": promise_id }),
Expand All @@ -49,14 +53,14 @@ pub fn wrap_json_op<D>(
zero_copy: Option<PinnedBuf>,
) -> CoreOp
where
D: FnOnce(Value, Option<PinnedBuf>) -> Result<JsonOp, ErrBox>,
D: FnOnce(Value, Option<PinnedBuf>) -> Result<JsonOp, JsonErrBox>,
{
let async_args: AsyncArgs = serde_json::from_slice(control).unwrap();
let promise_id = async_args.promise_id;
let is_sync = promise_id.is_none();

let result = serde_json::from_slice(control)
.map_err(ErrBox::from)
.map_err(JsonErrBox::from)
.and_then(move |args| d(args, zero_copy));

match result {
Expand Down Expand Up @@ -84,9 +88,9 @@ where

// This is just type conversion. Implement From trait?
// See https://github.com/tokio-rs/tokio/blob/ffd73a64e7ec497622b7f939e38017afe7124dc4/tokio-fs/src/lib.rs#L76-L85
fn convert_blocking_json<F>(f: F) -> Poll<Value, ErrBox>
fn convert_blocking_json<F>(f: F) -> Poll<Value, JsonErrBox>
where
F: FnOnce() -> Result<Value, ErrBox>,
F: FnOnce() -> Result<Value, JsonErrBox>,
{
use futures::Async::*;
match tokio_threadpool::blocking(f) {
Expand All @@ -97,9 +101,9 @@ where
}
}

pub fn blocking_json<F>(is_sync: bool, f: F) -> Result<JsonOp, ErrBox>
pub fn blocking_json<F>(is_sync: bool, f: F) -> Result<JsonOp, JsonErrBox>
where
F: 'static + Send + FnOnce() -> Result<Value, ErrBox>,
F: 'static + Send + FnOnce() -> Result<Value, JsonErrBox>,
{
if is_sync {
Ok(JsonOp::Sync(f()?))
Expand Down
2 changes: 1 addition & 1 deletion js/buffer_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ test(async function bufferTooLargeByteWrites(): Promise<void> {
err = e;
}

assertEquals(err.kind, Deno.ErrorKind.TooLarge);
assertEquals(err.kind, Deno.StandardErrorKinds.TooLarge);
assertEquals(err.name, "TooLarge");
});

Expand Down
8 changes: 4 additions & 4 deletions js/chmod_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ testPerm({ write: true }, function chmodSyncFailure(): void {
} catch (e) {
err = e;
}
assertEquals(err.kind, Deno.ErrorKind.NotFound);
assertEquals(err.kind, Deno.StandardErrorKinds.NotFound);
assertEquals(err.name, "NotFound");
});

Expand All @@ -67,7 +67,7 @@ testPerm({ write: false }, function chmodSyncPerm(): void {
} catch (e) {
err = e;
}
assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
assertEquals(err.kind, Deno.StandardErrorKinds.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});

Expand Down Expand Up @@ -126,7 +126,7 @@ testPerm({ write: true }, async function chmodFailure(): Promise<void> {
} catch (e) {
err = e;
}
assertEquals(err.kind, Deno.ErrorKind.NotFound);
assertEquals(err.kind, Deno.StandardErrorKinds.NotFound);
assertEquals(err.name, "NotFound");
});

Expand All @@ -137,6 +137,6 @@ testPerm({ write: false }, async function chmodPerm(): Promise<void> {
} catch (e) {
err = e;
}
assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
assertEquals(err.kind, Deno.StandardErrorKinds.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
Loading

0 comments on commit 4b3f6d9

Please sign in to comment.