refactor: use OpError instead of ErrBox for errors in ops (#4058)

To better reflect changes in error types in JS from #3662 this PR changes 
default error type used in ops from "ErrBox" to "OpError".

"OpError" is a type that can be sent over to JSON; it has all 
information needed to construct error in JavaScript. That
made "GetErrorKind" trait useless and so it was removed altogether.

To provide compatibility with previous use of "ErrBox" an implementation of
"From<ErrBox> for OpError" was added, however, it is an escape hatch and
ops implementors should strive to use "OpError" directly.
This commit is contained in:
Bartek Iwańczuk 2020-02-23 14:51:29 -05:00 committed by GitHub
parent 45eb2f9b37
commit 4e1abb4f3a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 794 additions and 836 deletions

View file

@ -9,6 +9,7 @@ use crate::file_fetcher::SourceFile;
use crate::file_fetcher::SourceFileFetcher;
use crate::global_state::GlobalState;
use crate::msg;
use crate::op_error::OpError;
use crate::ops::JsonResult;
use crate::source_maps::SourceMapGetter;
use crate::startup_data;
@ -633,7 +634,9 @@ async fn execute_in_thread_json(
req_msg: Buf,
global_state: GlobalState,
) -> JsonResult {
let msg = execute_in_thread(global_state, req_msg).await?;
let msg = execute_in_thread(global_state, req_msg)
.await
.map_err(|e| OpError::other(e.to_string()))?;
let json_str = std::str::from_utf8(&msg).unwrap();
Ok(json!(json_str))
}

View file

@ -1,410 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
//! This module implements error serialization; it
//! allows to serialize Rust errors to be sent to JS runtime.
//!
//! Currently it is deeply intertwined with `ErrBox` which is
//! not optimal since not every ErrBox can be "JS runtime error";
//! eg. there's no way to throw JSError/Diagnostic from within JS runtime
//!
//! There are many types of errors in Deno:
//! - ErrBox: a generic boxed object. This is the super type of all
//! errors handled in Rust.
//! - JSError: exceptions thrown from V8 into Rust. Usually a user exception.
//! These are basically a big JSON structure which holds information about
//! line numbers. We use this to pretty-print stack traces. These are
//! never passed back into the runtime.
//! - DenoError: these are errors that happen during ops, which are passed
//! back into the runtime, where an exception object is created and thrown.
//! DenoErrors have an integer code associated with them - access this via the kind() method.
//! - Diagnostic: these are errors that originate in TypeScript's compiler.
//! They're similar to JSError, in that they have line numbers.
//! But Diagnostics are compile-time type errors, whereas JSErrors are runtime exceptions.
//!
//! TODO:
//! - rename DenoError to OpError?
//! - rename JSError to RuntimeException. merge V8Exception?
//! - rename ErrorKind::Other. This corresponds to a generic exception thrown as the
//! global `Error` in JS:
//! https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
use crate::import_map::ImportMapError;
use deno_core::AnyError;
use deno_core::ErrBox;
use deno_core::ModuleResolutionError;
use dlopen::Error as DlopenError;
use reqwest;
use rustyline::error::ReadlineError;
use std;
use std::env::VarError;
use std::error::Error;
use std::fmt;
use std::io;
use url;
// Warning! The values in this enum are duplicated in js/errors.ts
// Update carefully!
#[allow(non_camel_case_types)]
#[repr(i8)]
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum ErrorKind {
NotFound = 1,
PermissionDenied = 2,
ConnectionRefused = 3,
ConnectionReset = 4,
ConnectionAborted = 5,
NotConnected = 6,
AddrInUse = 7,
AddrNotAvailable = 8,
BrokenPipe = 9,
AlreadyExists = 10,
InvalidData = 13,
TimedOut = 14,
Interrupted = 15,
WriteZero = 16,
UnexpectedEof = 17,
BadResource = 18,
Http = 19,
URIError = 20,
TypeError = 21,
Other = 22,
}
#[derive(Debug)]
pub struct DenoError {
kind: ErrorKind,
msg: String,
}
pub fn print_msg_and_exit(msg: &str) {
eprintln!("{}", msg);
std::process::exit(1);
}
pub fn print_err_and_exit(err: ErrBox) {
eprintln!("{}", err.to_string());
std::process::exit(1);
}
pub fn js_check(r: Result<(), ErrBox>) {
if let Err(err) = r {
print_err_and_exit(err);
}
}
impl DenoError {
pub fn new(kind: ErrorKind, msg: String) -> Self {
Self { kind, msg }
}
}
impl Error for DenoError {}
impl fmt::Display for DenoError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad(self.msg.as_str())
}
}
#[derive(Debug)]
struct StaticError(ErrorKind, &'static str);
impl Error for StaticError {}
impl fmt::Display for StaticError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad(self.1)
}
}
pub fn bad_resource() -> ErrBox {
StaticError(ErrorKind::BadResource, "bad resource id").into()
}
pub fn permission_denied() -> ErrBox {
StaticError(ErrorKind::PermissionDenied, "permission denied").into()
}
pub fn permission_denied_msg(msg: String) -> ErrBox {
DenoError::new(ErrorKind::PermissionDenied, msg).into()
}
pub fn no_buffer_specified() -> ErrBox {
StaticError(ErrorKind::TypeError, "no buffer specified").into()
}
pub fn invalid_address_syntax() -> ErrBox {
StaticError(ErrorKind::TypeError, "invalid address syntax").into()
}
pub fn other_error(msg: String) -> ErrBox {
DenoError::new(ErrorKind::Other, msg).into()
}
pub trait GetErrorKind {
fn kind(&self) -> ErrorKind;
}
impl GetErrorKind for DenoError {
fn kind(&self) -> ErrorKind {
self.kind
}
}
impl GetErrorKind for StaticError {
fn kind(&self) -> ErrorKind {
self.0
}
}
impl GetErrorKind for ImportMapError {
fn kind(&self) -> ErrorKind {
ErrorKind::Other
}
}
impl GetErrorKind for ModuleResolutionError {
fn kind(&self) -> ErrorKind {
ErrorKind::URIError
}
}
impl GetErrorKind for VarError {
fn kind(&self) -> ErrorKind {
use VarError::*;
match self {
NotPresent => ErrorKind::NotFound,
NotUnicode(..) => ErrorKind::InvalidData,
}
}
}
impl GetErrorKind for io::Error {
fn kind(&self) -> ErrorKind {
use io::ErrorKind::*;
match self.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,
InvalidInput => ErrorKind::TypeError,
InvalidData => ErrorKind::InvalidData,
TimedOut => ErrorKind::TimedOut,
Interrupted => ErrorKind::Interrupted,
WriteZero => ErrorKind::WriteZero,
UnexpectedEof => ErrorKind::UnexpectedEof,
WouldBlock => unreachable!(),
_ => ErrorKind::Other,
}
}
}
impl GetErrorKind for url::ParseError {
fn kind(&self) -> ErrorKind {
ErrorKind::URIError
}
}
impl GetErrorKind for reqwest::Error {
fn kind(&self) -> ErrorKind {
use self::GetErrorKind as Get;
match self.source() {
Some(err_ref) => None
.or_else(|| err_ref.downcast_ref::<url::ParseError>().map(Get::kind))
.or_else(|| err_ref.downcast_ref::<io::Error>().map(Get::kind))
.or_else(|| {
err_ref
.downcast_ref::<serde_json::error::Error>()
.map(Get::kind)
})
.unwrap_or_else(|| ErrorKind::Http),
None => ErrorKind::Http,
}
}
}
impl GetErrorKind for ReadlineError {
fn kind(&self) -> ErrorKind {
use ReadlineError::*;
match self {
Io(err) => GetErrorKind::kind(err),
Eof => ErrorKind::UnexpectedEof,
Interrupted => ErrorKind::Interrupted,
#[cfg(unix)]
Errno(err) => err.kind(),
_ => unimplemented!(),
}
}
}
impl GetErrorKind for serde_json::error::Error {
fn kind(&self) -> ErrorKind {
use serde_json::error::*;
match self.classify() {
Category::Io => ErrorKind::TypeError,
Category::Syntax => ErrorKind::TypeError,
Category::Data => ErrorKind::InvalidData,
Category::Eof => ErrorKind::UnexpectedEof,
}
}
}
#[cfg(unix)]
mod unix {
use super::{ErrorKind, GetErrorKind};
use nix::errno::Errno::*;
pub use nix::Error;
use nix::Error::Sys;
impl GetErrorKind for Error {
fn kind(&self) -> ErrorKind {
match self {
Sys(EPERM) => ErrorKind::PermissionDenied,
Sys(EINVAL) => ErrorKind::TypeError,
Sys(ENOENT) => ErrorKind::NotFound,
Sys(UnknownErrno) => unreachable!(),
Sys(_) => unreachable!(),
Error::InvalidPath => ErrorKind::TypeError,
Error::InvalidUtf8 => ErrorKind::InvalidData,
Error::UnsupportedOperation => unreachable!(),
}
}
}
}
impl GetErrorKind for DlopenError {
fn kind(&self) -> ErrorKind {
use dlopen::Error::*;
match self {
NullCharacter(_) => ErrorKind::Other,
OpeningLibraryError(e) => GetErrorKind::kind(e),
SymbolGettingError(e) => GetErrorKind::kind(e),
NullSymbol => ErrorKind::Other,
AddrNotMatchingDll(e) => GetErrorKind::kind(e),
}
}
}
impl GetErrorKind for dyn AnyError {
fn kind(&self) -> ErrorKind {
use self::GetErrorKind as Get;
#[cfg(unix)]
fn unix_error_kind(err: &dyn AnyError) -> Option<ErrorKind> {
err.downcast_ref::<unix::Error>().map(Get::kind)
}
#[cfg(not(unix))]
fn unix_error_kind(_: &dyn AnyError) -> Option<ErrorKind> {
None
}
None
.or_else(|| self.downcast_ref::<DenoError>().map(Get::kind))
.or_else(|| self.downcast_ref::<reqwest::Error>().map(Get::kind))
.or_else(|| self.downcast_ref::<ImportMapError>().map(Get::kind))
.or_else(|| self.downcast_ref::<io::Error>().map(Get::kind))
.or_else(|| self.downcast_ref::<ModuleResolutionError>().map(Get::kind))
.or_else(|| self.downcast_ref::<StaticError>().map(Get::kind))
.or_else(|| self.downcast_ref::<url::ParseError>().map(Get::kind))
.or_else(|| self.downcast_ref::<VarError>().map(Get::kind))
.or_else(|| self.downcast_ref::<ReadlineError>().map(Get::kind))
.or_else(|| {
self
.downcast_ref::<serde_json::error::Error>()
.map(Get::kind)
})
.or_else(|| self.downcast_ref::<DlopenError>().map(Get::kind))
.or_else(|| unix_error_kind(self))
.unwrap_or_else(|| {
panic!("Can't get ErrorKind for {:?}", self);
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use deno_core::ErrBox;
fn io_error() -> io::Error {
io::Error::from(io::ErrorKind::NotFound)
}
fn url_error() -> url::ParseError {
url::ParseError::EmptyHost
}
fn import_map_error() -> ImportMapError {
ImportMapError {
msg: "an import map error".to_string(),
}
}
#[test]
fn test_simple_error() {
let err =
ErrBox::from(DenoError::new(ErrorKind::NotFound, "foo".to_string()));
assert_eq!(err.kind(), ErrorKind::NotFound);
assert_eq!(err.to_string(), "foo");
}
#[test]
fn test_io_error() {
let err = ErrBox::from(io_error());
assert_eq!(err.kind(), ErrorKind::NotFound);
assert_eq!(err.to_string(), "entity not found");
}
#[test]
fn test_url_error() {
let err = ErrBox::from(url_error());
assert_eq!(err.kind(), ErrorKind::URIError);
assert_eq!(err.to_string(), "empty host");
}
// TODO find a way to easily test tokio errors and unix errors
#[test]
fn test_import_map_error() {
let err = ErrBox::from(import_map_error());
assert_eq!(err.kind(), ErrorKind::Other);
assert_eq!(err.to_string(), "an import map error");
}
#[test]
fn test_bad_resource() {
let err = bad_resource();
assert_eq!(err.kind(), ErrorKind::BadResource);
assert_eq!(err.to_string(), "bad resource id");
}
#[test]
fn test_permission_denied() {
let err = permission_denied();
assert_eq!(err.kind(), ErrorKind::PermissionDenied);
assert_eq!(err.to_string(), "permission denied");
}
#[test]
fn test_permission_denied_msg() {
let err =
permission_denied_msg("run again with the --allow-net flag".to_string());
assert_eq!(err.kind(), ErrorKind::PermissionDenied);
assert_eq!(err.to_string(), "run again with the --allow-net flag");
}
#[test]
fn test_no_buffer_specified() {
let err = no_buffer_specified();
assert_eq!(err.kind(), ErrorKind::TypeError);
assert_eq!(err.to_string(), "no buffer specified");
}
}

View file

@ -1,13 +1,11 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::colors;
use crate::deno_error::DenoError;
use crate::deno_error::ErrorKind;
use crate::deno_error::GetErrorKind;
use crate::http_cache::HttpCache;
use crate::http_util;
use crate::http_util::create_http_client;
use crate::http_util::FetchOnceResult;
use crate::msg;
use crate::op_error::OpError;
use deno_core::ErrBox;
use deno_core::ModuleSpecifier;
use futures::future::FutureExt;
@ -100,8 +98,7 @@ impl SourceFileFetcher {
fn check_if_supported_scheme(url: &Url) -> Result<(), ErrBox> {
if !SUPPORTED_URL_SCHEMES.contains(&url.scheme()) {
return Err(
DenoError::new(
ErrorKind::Other,
OpError::other(
format!("Unsupported scheme \"{}\" for module \"{}\". Supported schemes: {:#?}", url.scheme(), url, SUPPORTED_URL_SCHEMES),
).into()
);
@ -174,7 +171,15 @@ impl SourceFileFetcher {
Ok(file)
}
Err(err) => {
let err_kind = err.kind();
// FIXME(bartlomieju): rewrite this whole block
// FIXME(bartlomieju): very ugly
let mut is_not_found = false;
if let Some(e) = err.downcast_ref::<std::io::Error>() {
if e.kind() == std::io::ErrorKind::NotFound {
is_not_found = true;
}
}
let referrer_suffix = if let Some(referrer) = maybe_referrer {
format!(r#" from "{}""#, referrer)
} else {
@ -187,13 +192,13 @@ impl SourceFileFetcher {
r#"Cannot find module "{}"{} in cache, --cached-only is specified"#,
module_url, referrer_suffix
);
DenoError::new(ErrorKind::NotFound, msg).into()
} else if err_kind == ErrorKind::NotFound {
OpError::not_found(msg).into()
} else if is_not_found {
let msg = format!(
r#"Cannot resolve module "{}"{}"#,
module_url, referrer_suffix
);
DenoError::new(ErrorKind::NotFound, msg).into()
OpError::not_found(msg).into()
} else {
err
};
@ -250,8 +255,7 @@ impl SourceFileFetcher {
/// Fetch local source file.
fn fetch_local_file(&self, module_url: &Url) -> Result<SourceFile, ErrBox> {
let filepath = module_url.to_file_path().map_err(|()| {
ErrBox::from(DenoError::new(
ErrorKind::URIError,
ErrBox::from(OpError::uri_error(
"File URL contains invalid path".to_owned(),
))
})?;
@ -350,7 +354,7 @@ impl SourceFileFetcher {
redirect_limit: i64,
) -> Pin<Box<dyn Future<Output = Result<SourceFile, ErrBox>>>> {
if redirect_limit < 0 {
let e = DenoError::new(ErrorKind::Http, "too many redirects".to_string());
let e = OpError::http("too many redirects".to_string());
return futures::future::err(e.into()).boxed_local();
}
@ -1078,8 +1082,9 @@ mod tests {
.fetch_remote_source_async(&double_redirect_url, false, false, 1)
.await;
assert!(result.is_err());
let err = result.err().unwrap();
assert_eq!(err.kind(), ErrorKind::Http);
// FIXME(bartlomieju):
// let err = result.err().unwrap();
// assert_eq!(err.kind(), ErrorKind::Http);
drop(http_server_guard);
}
@ -1095,8 +1100,9 @@ mod tests {
.get_source_file_async(&module_url, true, true, false)
.await;
assert!(result.is_err());
let err = result.err().unwrap();
assert_eq!(err.kind(), ErrorKind::NotFound);
// FIXME(bartlomieju):
// let err = result.err().unwrap();
// assert_eq!(err.kind(), ErrorKind::NotFound);
drop(http_server_guard);
}
@ -1117,8 +1123,9 @@ mod tests {
.get_source_file_async(&module_url, true, false, true)
.await;
assert!(result.is_err());
let err = result.err().unwrap();
assert_eq!(err.kind(), ErrorKind::NotFound);
// FIXME(bartlomieju):
// let err = result.err().unwrap();
// assert_eq!(err.kind(), ErrorKind::NotFound);
// download and cache file
let result = fetcher_1
@ -1313,12 +1320,7 @@ mod tests {
for &test in test_cases.iter() {
let url = Url::parse(test).unwrap();
assert_eq!(
SourceFileFetcher::check_if_supported_scheme(&url)
.unwrap_err()
.kind(),
ErrorKind::Other
);
assert!(SourceFileFetcher::check_if_supported_scheme(&url).is_err());
}
}

View file

@ -84,12 +84,15 @@ fn check_source_files(
} else {
"files"
};
Err(crate::deno_error::other_error(format!(
"Found {} not formatted {} in {:?}",
not_formatted_files.len(),
f,
duration
)))
Err(
crate::op_error::OpError::other(format!(
"Found {} not formatted {} in {:?}",
not_formatted_files.len(),
f,
duration
))
.into(),
)
}
}

View file

@ -136,9 +136,11 @@ pub fn chown(path: &str, uid: u32, gid: u32) -> Result<(), ErrBox> {
pub fn chown(_path: &str, _uid: u32, _gid: u32) -> Result<(), ErrBox> {
// Noop
// TODO: implement chown for Windows
Err(crate::deno_error::other_error(
let e = std::io::Error::new(
std::io::ErrorKind::Other,
"Op not implemented".to_string(),
))
);
Err(ErrBox::from(e))
}
pub fn resolve_from_cwd(path: &Path) -> Result<PathBuf, ErrBox> {

View file

@ -6,7 +6,6 @@ use crate::compilers::TargetLib;
use crate::compilers::TsCompiler;
use crate::compilers::WasmCompiler;
use crate::deno_dir;
use crate::deno_error::permission_denied;
use crate::file_fetcher::SourceFileFetcher;
use crate::flags;
use crate::http_cache;
@ -18,8 +17,6 @@ use deno_core::ModuleSpecifier;
use std;
use std::env;
use std::ops::Deref;
use std::path::Path;
use std::str;
use std::sync::atomic::AtomicUsize;
use std::sync::Arc;
use std::sync::Mutex;
@ -172,60 +169,6 @@ impl GlobalState {
Ok(compiled_module)
}
#[inline]
pub fn check_read(&self, filename: &Path) -> Result<(), ErrBox> {
self.permissions.check_read(filename)
}
#[inline]
pub fn check_write(&self, filename: &Path) -> Result<(), ErrBox> {
self.permissions.check_write(filename)
}
#[inline]
pub fn check_env(&self) -> Result<(), ErrBox> {
self.permissions.check_env()
}
#[inline]
pub fn check_net(&self, hostname: &str, port: u16) -> Result<(), ErrBox> {
self.permissions.check_net(hostname, port)
}
#[inline]
pub fn check_net_url(&self, url: &url::Url) -> Result<(), ErrBox> {
self.permissions.check_net_url(url)
}
#[inline]
pub fn check_run(&self) -> Result<(), ErrBox> {
self.permissions.check_run()
}
pub fn check_dyn_import(
&self,
module_specifier: &ModuleSpecifier,
) -> Result<(), ErrBox> {
let u = module_specifier.as_url();
match u.scheme() {
"http" | "https" => {
self.check_net_url(u)?;
Ok(())
}
"file" => {
let filename = u
.to_file_path()
.unwrap()
.into_os_string()
.into_string()
.unwrap();
self.check_read(Path::new(&filename))?;
Ok(())
}
_ => Err(permission_denied()),
}
}
#[cfg(test)]
pub fn mock(argv: Vec<String>) -> GlobalState {
GlobalState::new(flags::DenoFlags {

View file

@ -1,7 +1,4 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::deno_error;
use crate::deno_error::DenoError;
use crate::deno_error::ErrorKind;
use crate::version;
use bytes::Bytes;
use deno_core::ErrBox;
@ -49,8 +46,8 @@ pub fn create_http_client(ca_file: Option<String>) -> Result<Client, ErrBox> {
}
builder.build().map_err(|_| {
ErrBox::from(DenoError::new(
ErrorKind::Other,
ErrBox::from(io::Error::new(
io::ErrorKind::Other,
"Unable to build http client".to_string(),
))
})
@ -145,8 +142,8 @@ pub fn fetch_once(
if response.status().is_client_error()
|| response.status().is_server_error()
{
let err = DenoError::new(
deno_error::ErrorKind::Other,
let err = io::Error::new(
io::ErrorKind::Other,
format!("Import '{}' failed: {}", &url, response.status()),
);
return Err(err.into());

View file

@ -23,7 +23,6 @@ mod checksum;
pub mod colors;
pub mod compilers;
pub mod deno_dir;
pub mod deno_error;
pub mod diagnostics;
mod disk_cache;
mod file_fetcher;
@ -41,6 +40,7 @@ mod js;
mod lockfile;
mod metrics;
pub mod msg;
pub mod op_error;
pub mod ops;
pub mod permissions;
mod repl;

462
cli/op_error.rs Normal file
View file

@ -0,0 +1,462 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
//! There are many types of errors in Deno:
//! - ErrBox: a generic boxed object. This is the super type of all
//! errors handled in Rust.
//! - JSError: exceptions thrown from V8 into Rust. Usually a user exception.
//! These are basically a big JSON structure which holds information about
//! line numbers. We use this to pretty-print stack traces. These are
//! never passed back into the runtime.
//! - OpError: these are errors that happen during ops, which are passed
//! back into the runtime, where an exception object is created and thrown.
//! OpErrors have an integer code associated with them - access this via the `kind` field.
//! - Diagnostic: these are errors that originate in TypeScript's compiler.
//! They're similar to JSError, in that they have line numbers.
//! But Diagnostics are compile-time type errors, whereas JSErrors are runtime exceptions.
//!
//! TODO:
//! - rename/merge JSError with V8Exception?
use crate::import_map::ImportMapError;
use deno_core::ErrBox;
use deno_core::ModuleResolutionError;
use dlopen;
use reqwest;
use rustyline::error::ReadlineError;
use std;
use std::env::VarError;
use std::error::Error;
use std::fmt;
use std::io;
use url;
// Warning! The values in this enum are duplicated in js/errors.ts
// Update carefully!
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum ErrorKind {
NotFound = 1,
PermissionDenied = 2,
ConnectionRefused = 3,
ConnectionReset = 4,
ConnectionAborted = 5,
NotConnected = 6,
AddrInUse = 7,
AddrNotAvailable = 8,
BrokenPipe = 9,
AlreadyExists = 10,
InvalidData = 13,
TimedOut = 14,
Interrupted = 15,
WriteZero = 16,
UnexpectedEof = 17,
BadResource = 18,
Http = 19,
URIError = 20,
TypeError = 21,
/// This maps to window.Error - ie. a generic error type
/// if no better context is available.
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
Other = 22,
}
#[derive(Debug)]
pub struct OpError {
pub kind: ErrorKind,
pub msg: String,
}
impl OpError {
fn new(kind: ErrorKind, msg: String) -> Self {
Self { kind, msg }
}
pub fn not_found(msg: String) -> Self {
Self::new(ErrorKind::NotFound, msg)
}
pub fn other(msg: String) -> Self {
Self::new(ErrorKind::Other, msg)
}
pub fn type_error(msg: String) -> Self {
Self::new(ErrorKind::TypeError, msg)
}
pub fn http(msg: String) -> Self {
Self::new(ErrorKind::Http, msg)
}
pub fn uri_error(msg: String) -> Self {
Self::new(ErrorKind::URIError, msg)
}
pub fn permission_denied(msg: String) -> OpError {
Self::new(ErrorKind::PermissionDenied, msg)
}
pub fn bad_resource() -> OpError {
Self::new(ErrorKind::BadResource, "bad resource id".to_string())
}
}
impl Error for OpError {}
impl fmt::Display for OpError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad(self.msg.as_str())
}
}
impl From<ImportMapError> for OpError {
fn from(error: ImportMapError) -> Self {
OpError::from(&error)
}
}
impl From<&ImportMapError> for OpError {
fn from(error: &ImportMapError) -> Self {
Self {
kind: ErrorKind::Other,
msg: error.to_string(),
}
}
}
impl From<ModuleResolutionError> for OpError {
fn from(error: ModuleResolutionError) -> Self {
OpError::from(&error)
}
}
impl From<&ModuleResolutionError> for OpError {
fn from(error: &ModuleResolutionError) -> Self {
Self {
kind: ErrorKind::URIError,
msg: error.to_string(),
}
}
}
impl From<VarError> for OpError {
fn from(error: VarError) -> Self {
OpError::from(&error)
}
}
impl From<&VarError> for OpError {
fn from(error: &VarError) -> Self {
use VarError::*;
let kind = match error {
NotPresent => ErrorKind::NotFound,
NotUnicode(..) => ErrorKind::InvalidData,
};
Self {
kind,
msg: error.to_string(),
}
}
}
impl From<io::Error> for OpError {
fn from(error: io::Error) -> Self {
OpError::from(&error)
}
}
impl From<&io::Error> for OpError {
fn from(error: &io::Error) -> Self {
use io::ErrorKind::*;
let kind = match error.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,
InvalidInput => ErrorKind::TypeError,
InvalidData => ErrorKind::InvalidData,
TimedOut => ErrorKind::TimedOut,
Interrupted => ErrorKind::Interrupted,
WriteZero => ErrorKind::WriteZero,
UnexpectedEof => ErrorKind::UnexpectedEof,
Other => ErrorKind::Other,
WouldBlock => unreachable!(),
// Non-exhaustive enum - might add new variants
// in the future
_ => unreachable!(),
};
Self {
kind,
msg: error.to_string(),
}
}
}
impl From<url::ParseError> for OpError {
fn from(error: url::ParseError) -> Self {
OpError::from(&error)
}
}
impl From<&url::ParseError> for OpError {
fn from(error: &url::ParseError) -> Self {
Self {
kind: ErrorKind::URIError,
msg: error.to_string(),
}
}
}
impl From<reqwest::Error> for OpError {
fn from(error: reqwest::Error) -> Self {
OpError::from(&error)
}
}
impl From<&reqwest::Error> for OpError {
fn from(error: &reqwest::Error) -> Self {
match error.source() {
Some(err_ref) => None
.or_else(|| {
err_ref
.downcast_ref::<url::ParseError>()
.map(|e| e.clone().into())
})
.or_else(|| {
err_ref
.downcast_ref::<io::Error>()
.map(|e| e.to_owned().into())
})
.or_else(|| {
err_ref
.downcast_ref::<serde_json::error::Error>()
.map(|e| e.into())
})
.unwrap_or_else(|| Self {
kind: ErrorKind::Http,
msg: error.to_string(),
}),
None => Self {
kind: ErrorKind::Http,
msg: error.to_string(),
},
}
}
}
impl From<ReadlineError> for OpError {
fn from(error: ReadlineError) -> Self {
OpError::from(&error)
}
}
impl From<&ReadlineError> for OpError {
fn from(error: &ReadlineError) -> Self {
use ReadlineError::*;
let kind = match error {
Io(err) => return err.into(),
Eof => ErrorKind::UnexpectedEof,
Interrupted => ErrorKind::Interrupted,
#[cfg(unix)]
Errno(err) => return err.into(),
_ => unimplemented!(),
};
Self {
kind,
msg: error.to_string(),
}
}
}
impl From<serde_json::error::Error> for OpError {
fn from(error: serde_json::error::Error) -> Self {
OpError::from(&error)
}
}
impl From<&serde_json::error::Error> for OpError {
fn from(error: &serde_json::error::Error) -> Self {
use serde_json::error::*;
let kind = match error.classify() {
Category::Io => ErrorKind::TypeError,
Category::Syntax => ErrorKind::TypeError,
Category::Data => ErrorKind::InvalidData,
Category::Eof => ErrorKind::UnexpectedEof,
};
Self {
kind,
msg: error.to_string(),
}
}
}
#[cfg(unix)]
mod unix {
use super::{ErrorKind, OpError};
use nix::errno::Errno::*;
pub use nix::Error;
use nix::Error::Sys;
impl From<Error> for OpError {
fn from(error: Error) -> Self {
OpError::from(&error)
}
}
impl From<&Error> for OpError {
fn from(error: &Error) -> Self {
let kind = match error {
Sys(EPERM) => ErrorKind::PermissionDenied,
Sys(EINVAL) => ErrorKind::TypeError,
Sys(ENOENT) => ErrorKind::NotFound,
Sys(UnknownErrno) => unreachable!(),
Sys(_) => unreachable!(),
Error::InvalidPath => ErrorKind::TypeError,
Error::InvalidUtf8 => ErrorKind::InvalidData,
Error::UnsupportedOperation => unreachable!(),
};
Self {
kind,
msg: error.to_string(),
}
}
}
}
impl From<dlopen::Error> for OpError {
fn from(error: dlopen::Error) -> Self {
OpError::from(&error)
}
}
impl From<&dlopen::Error> for OpError {
fn from(error: &dlopen::Error) -> Self {
use dlopen::Error::*;
let kind = match error {
NullCharacter(_) => ErrorKind::Other,
OpeningLibraryError(e) => return e.into(),
SymbolGettingError(e) => return e.into(),
AddrNotMatchingDll(e) => return e.into(),
NullSymbol => ErrorKind::Other,
};
Self {
kind,
msg: error.to_string(),
}
}
}
impl From<ErrBox> for OpError {
fn from(error: ErrBox) -> Self {
#[cfg(unix)]
fn unix_error_kind(err: &ErrBox) -> Option<OpError> {
err.downcast_ref::<unix::Error>().map(|e| e.into())
}
#[cfg(not(unix))]
fn unix_error_kind(_: &ErrBox) -> Option<OpError> {
None
}
None
.or_else(|| {
error
.downcast_ref::<OpError>()
.map(|e| OpError::new(e.kind, e.msg.to_string()))
})
.or_else(|| error.downcast_ref::<reqwest::Error>().map(|e| e.into()))
.or_else(|| error.downcast_ref::<ImportMapError>().map(|e| e.into()))
.or_else(|| error.downcast_ref::<io::Error>().map(|e| e.into()))
.or_else(|| {
error
.downcast_ref::<ModuleResolutionError>()
.map(|e| e.into())
})
.or_else(|| error.downcast_ref::<url::ParseError>().map(|e| e.into()))
.or_else(|| error.downcast_ref::<VarError>().map(|e| e.into()))
.or_else(|| error.downcast_ref::<ReadlineError>().map(|e| e.into()))
.or_else(|| {
error
.downcast_ref::<serde_json::error::Error>()
.map(|e| e.into())
})
.or_else(|| error.downcast_ref::<dlopen::Error>().map(|e| e.into()))
.or_else(|| unix_error_kind(&error))
.unwrap_or_else(|| {
panic!("Can't downcast {:?} to OpError", error);
})
}
}
#[cfg(test)]
mod tests {
use super::*;
fn io_error() -> io::Error {
io::Error::from(io::ErrorKind::NotFound)
}
fn url_error() -> url::ParseError {
url::ParseError::EmptyHost
}
fn import_map_error() -> ImportMapError {
ImportMapError {
msg: "an import map error".to_string(),
}
}
#[test]
fn test_simple_error() {
let err = OpError::not_found("foo".to_string());
assert_eq!(err.kind, ErrorKind::NotFound);
assert_eq!(err.to_string(), "foo");
}
#[test]
fn test_io_error() {
let err = OpError::from(io_error());
assert_eq!(err.kind, ErrorKind::NotFound);
assert_eq!(err.to_string(), "entity not found");
}
#[test]
fn test_url_error() {
let err = OpError::from(url_error());
assert_eq!(err.kind, ErrorKind::URIError);
assert_eq!(err.to_string(), "empty host");
}
// TODO find a way to easily test tokio errors and unix errors
#[test]
fn test_import_map_error() {
let err = OpError::from(import_map_error());
assert_eq!(err.kind, ErrorKind::Other);
assert_eq!(err.to_string(), "an import map error");
}
#[test]
fn test_bad_resource() {
let err = OpError::bad_resource();
assert_eq!(err.kind, ErrorKind::BadResource);
assert_eq!(err.to_string(), "bad resource id");
}
#[test]
fn test_permission_denied() {
let err = OpError::permission_denied(
"run again with the --allow-net flag".to_string(),
);
assert_eq!(err.kind, ErrorKind::PermissionDenied);
assert_eq!(err.to_string(), "run again with the --allow-net flag");
}
}

View file

@ -4,6 +4,7 @@ use super::dispatch_json::JsonOp;
use super::dispatch_json::Value;
use crate::futures::future::try_join_all;
use crate::msg;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use deno_core::Loader;
@ -38,7 +39,7 @@ fn op_cache(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: CacheArgs = serde_json::from_value(args)?;
let module_specifier = ModuleSpecifier::resolve_url(&args.module_id)
@ -66,7 +67,7 @@ fn op_resolve_modules(
state: &State,
args: Value,
_data: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: SpecifiersReferrerArgs = serde_json::from_value(args)?;
let (referrer, is_main) = if let Some(referrer) = args.referrer {
(referrer, false)
@ -77,11 +78,10 @@ fn op_resolve_modules(
let mut specifiers = vec![];
for specifier in &args.specifiers {
let resolved_specifier = state.resolve(specifier, &referrer, is_main);
match resolved_specifier {
Ok(ms) => specifiers.push(ms.as_str().to_owned()),
Err(err) => return Err(err),
}
let specifier = state
.resolve(specifier, &referrer, is_main)
.map_err(OpError::from)?;
specifiers.push(specifier.as_str().to_owned());
}
Ok(JsonOp::Sync(json!(specifiers)))
@ -91,7 +91,7 @@ fn op_fetch_source_files(
state: &State,
args: Value,
_data: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: SpecifiersReferrerArgs = serde_json::from_value(args)?;
let ref_specifier = if let Some(referrer) = args.referrer {
@ -122,7 +122,7 @@ fn op_fetch_source_files(
})
.collect();
let files = try_join_all(file_futures).await?;
let files = try_join_all(file_futures).await.map_err(OpError::from)?;
// We want to get an array of futures that resolves to
let v = files.into_iter().map(|f| {
async {
@ -134,7 +134,8 @@ fn op_fetch_source_files(
global_state
.file_fetcher
.fetch_source_file_async(&types_specifier, ref_specifier.clone())
.await?
.await
.map_err(OpError::from)?
}
_ => f,
};
@ -146,12 +147,13 @@ fn op_fetch_source_files(
global_state
.wasm_compiler
.compile_async(global_state.clone(), &file)
.await?
.await
.map_err(|e| OpError::other(e.to_string()))?
.code
}
_ => String::from_utf8(file.source_code).unwrap(),
};
Ok::<_, ErrBox>(json!({
Ok::<_, OpError>(json!({
"url": file.url.to_string(),
"filename": file.filename.to_str().unwrap(),
"mediaType": file.media_type as i32,
@ -177,7 +179,7 @@ fn op_fetch_asset(
_state: &State,
args: Value,
_data: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: FetchRemoteAssetArgs = serde_json::from_value(args)?;
debug!("args.name: {}", args.name);

View file

@ -1,4 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::op_error::OpError;
use deno_core::*;
use futures::future::FutureExt;
pub use serde_derive::Deserialize;
@ -7,7 +8,7 @@ pub use serde_json::Value;
use std::future::Future;
use std::pin::Pin;
pub type JsonResult = Result<Value, ErrBox>;
pub type JsonResult = Result<Value, OpError>;
pub type AsyncJsonOp = Pin<Box<dyn Future<Output = JsonResult>>>;
@ -19,11 +20,10 @@ pub enum JsonOp {
AsyncUnref(AsyncJsonOp),
}
fn json_err(err: ErrBox) -> Value {
use crate::deno_error::GetErrorKind;
fn json_err(err: OpError) -> Value {
json!({
"message": err.to_string(),
"kind": err.kind() as u32,
"message": err.msg,
"kind": err.kind as u32,
})
}
@ -43,13 +43,13 @@ struct AsyncArgs {
pub fn json_op<D>(d: D) -> impl Fn(&[u8], Option<ZeroCopyBuf>) -> CoreOp
where
D: Fn(Value, Option<ZeroCopyBuf>) -> Result<JsonOp, ErrBox>,
D: Fn(Value, Option<ZeroCopyBuf>) -> Result<JsonOp, OpError>,
{
move |control: &[u8], zero_copy: Option<ZeroCopyBuf>| {
let async_args: AsyncArgs = match serde_json::from_slice(control) {
Ok(args) => args,
Err(e) => {
let buf = serialize_result(None, Err(ErrBox::from(e)));
let buf = serialize_result(None, Err(OpError::from(e)));
return CoreOp::Sync(buf);
}
};
@ -57,7 +57,7 @@ where
let is_sync = promise_id.is_none();
let result = serde_json::from_slice(control)
.map_err(ErrBox::from)
.map_err(OpError::from)
.and_then(|args| d(args, zero_copy));
// Convert to CoreOp
@ -92,7 +92,7 @@ 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, OpError>
where
F: 'static + Send + FnOnce() -> JsonResult,
{

View file

@ -4,19 +4,17 @@
//! alternative to flatbuffers using a very simple list of int32s to lay out
//! messages. The first i32 is used to determine if a message a flatbuffer
//! message or a "minimal" message.
use crate::deno_error::ErrorKind;
use crate::deno_error::GetErrorKind;
use crate::op_error::OpError;
use byteorder::{LittleEndian, WriteBytesExt};
use deno_core::Buf;
use deno_core::CoreOp;
use deno_core::ErrBox;
use deno_core::Op;
use deno_core::ZeroCopyBuf;
use futures::future::FutureExt;
use std::future::Future;
use std::pin::Pin;
pub type MinimalOp = dyn Future<Output = Result<i32, ErrBox>>;
pub type MinimalOp = dyn Future<Output = Result<i32, OpError>>;
#[derive(Copy, Clone, Debug, PartialEq)]
// This corresponds to RecordMinimal on the TS side.
@ -121,14 +119,12 @@ where
let mut record = match parse_min_record(control) {
Some(r) => r,
None => {
let e = OpError::type_error("Unparsable control buffer".to_string());
let error_record = ErrorRecord {
promise_id: 0,
arg: -1,
error_code: ErrorKind::TypeError as i32,
error_message: "Unparsable control buffer"
.to_string()
.as_bytes()
.to_owned(),
error_code: e.kind as i32,
error_message: e.msg.as_bytes().to_owned(),
};
return Op::Sync(error_record.into());
}
@ -148,8 +144,8 @@ where
let error_record = ErrorRecord {
promise_id: record.promise_id,
arg: -1,
error_code: err.kind() as i32,
error_message: err.to_string().as_bytes().to_owned(),
error_code: err.kind as i32,
error_message: err.msg.as_bytes().to_owned(),
};
Ok(error_record.into())
}

View file

@ -1,6 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use crate::fmt_errors::JSError;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::source_maps::get_orig_position;
use crate::source_maps::CachedMaps;
@ -28,7 +29,7 @@ fn op_format_error(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: FormatErrorArgs = serde_json::from_value(args)?;
let error =
JSError::from_json(&args.error, &state.borrow().global_state.ts_compiler);
@ -49,7 +50,7 @@ fn op_apply_source_map(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ApplySourceMap = serde_json::from_value(args)?;
let mut mappings_map: CachedMaps = HashMap::new();

View file

@ -1,9 +1,8 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use super::io::StreamResource;
use crate::deno_error::DenoError;
use crate::deno_error::ErrorKind;
use crate::http_util::{create_http_client, HttpBody};
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use deno_core::*;
@ -29,7 +28,7 @@ pub fn op_fetch(
state: &State,
args: Value,
data: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: FetchArgs = serde_json::from_value(args)?;
let url = args.url;
@ -37,22 +36,20 @@ pub fn op_fetch(
create_http_client(state.borrow().global_state.flags.ca_file.clone())?;
let method = match args.method {
Some(method_str) => Method::from_bytes(method_str.as_bytes())?,
Some(method_str) => Method::from_bytes(method_str.as_bytes())
.map_err(|e| OpError::other(e.to_string()))?,
None => Method::GET,
};
let url_ = url::Url::parse(&url).map_err(ErrBox::from)?;
let url_ = url::Url::parse(&url).map_err(OpError::from)?;
// Check scheme before asking for net permission
let scheme = url_.scheme();
if scheme != "http" && scheme != "https" {
return Err(
DenoError::new(
ErrorKind::TypeError,
format!("scheme '{}' not supported", scheme),
)
.into(),
);
return Err(OpError::type_error(format!(
"scheme '{}' not supported",
scheme
)));
}
state.check_net_url(&url_)?;

View file

@ -1,10 +1,8 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use super::io::StreamResource;
use crate::deno_error::bad_resource;
use crate::deno_error::DenoError;
use crate::deno_error::ErrorKind;
use crate::fs as deno_fs;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use deno_core::*;
@ -46,7 +44,7 @@ fn op_open(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: OpenArgs = serde_json::from_value(args)?;
let filename = deno_fs::resolve_from_cwd(Path::new(&args.filename))?;
let state_ = state.clone();
@ -113,17 +111,14 @@ fn op_open(
open_options.create_new(true).read(true).write(true);
}
&_ => {
return Err(ErrBox::from(DenoError::new(
ErrorKind::Other,
"Unknown open mode.".to_string(),
)));
// TODO: this should be type error
return Err(OpError::other("Unknown open mode.".to_string()));
}
}
} else {
return Err(ErrBox::from(DenoError::new(
ErrorKind::Other,
return Err(OpError::other(
"Open requires either mode or options.".to_string(),
)));
));
};
let is_sync = args.promise_id.is_none();
@ -154,14 +149,14 @@ fn op_close(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: CloseArgs = serde_json::from_value(args)?;
let mut state = state.borrow_mut();
state
.resource_table
.close(args.rid as u32)
.ok_or_else(bad_resource)?;
.ok_or_else(OpError::bad_resource)?;
Ok(JsonOp::Sync(json!({})))
}
@ -178,7 +173,7 @@ fn op_seek(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: SeekArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let offset = args.offset;
@ -189,9 +184,9 @@ fn op_seek(
1 => SeekFrom::Current(i64::from(offset)),
2 => SeekFrom::End(i64::from(offset)),
_ => {
return Err(ErrBox::from(DenoError::new(
ErrorKind::TypeError,
format!("Invalid seek mode: {}", whence),
return Err(OpError::type_error(format!(
"Invalid seek mode: {}",
whence
)));
}
};
@ -200,11 +195,11 @@ fn op_seek(
let resource = state
.resource_table
.get::<StreamResource>(rid)
.ok_or_else(bad_resource)?;
.ok_or_else(OpError::bad_resource)?;
let tokio_file = match resource {
StreamResource::FsFile(ref file) => file,
_ => return Err(bad_resource()),
_ => return Err(OpError::bad_resource()),
};
let mut file = futures::executor::block_on(tokio_file.try_clone())?;

View file

@ -1,9 +1,8 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
// Some deserializer fields are only used on Unix and Windows build fails without it
use super::dispatch_json::{blocking_json, Deserialize, JsonOp, Value};
use crate::deno_error::DenoError;
use crate::deno_error::ErrorKind;
use crate::fs as deno_fs;
use crate::op_error::OpError;
use crate::ops::dispatch_json::JsonResult;
use crate::ops::json_op;
use crate::state::State;
@ -55,7 +54,7 @@ fn op_chdir(
_state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ChdirArgs = serde_json::from_value(args)?;
std::env::set_current_dir(&args.directory)?;
Ok(JsonOp::Sync(json!({})))
@ -74,7 +73,7 @@ fn op_mkdir(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: MkdirArgs = serde_json::from_value(args)?;
let path = deno_fs::resolve_from_cwd(Path::new(&args.path))?;
@ -101,7 +100,7 @@ fn op_chmod(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ChmodArgs = serde_json::from_value(args)?;
let path = deno_fs::resolve_from_cwd(Path::new(&args.path))?;
@ -135,7 +134,7 @@ fn op_chown(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ChownArgs = serde_json::from_value(args)?;
let path = deno_fs::resolve_from_cwd(Path::new(&args.path))?;
@ -146,7 +145,7 @@ fn op_chown(
debug!("op_chown {}", path.display());
match deno_fs::chown(args.path.as_ref(), args.uid, args.gid) {
Ok(_) => Ok(json!({})),
Err(e) => Err(e),
Err(e) => Err(OpError::from(e)),
}
})
}
@ -163,7 +162,7 @@ fn op_remove(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: RemoveArgs = serde_json::from_value(args)?;
let path = deno_fs::resolve_from_cwd(Path::new(&args.path))?;
let recursive = args.recursive;
@ -198,7 +197,7 @@ fn op_copy_file(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: CopyFileArgs = serde_json::from_value(args)?;
let from = deno_fs::resolve_from_cwd(Path::new(&args.from))?;
let to = deno_fs::resolve_from_cwd(Path::new(&args.to))?;
@ -213,10 +212,7 @@ fn op_copy_file(
// See https://github.com/rust-lang/rust/issues/54800
// Once the issue is reolved, we should remove this workaround.
if cfg!(unix) && !from.is_file() {
return Err(
DenoError::new(ErrorKind::NotFound, "File not found".to_string())
.into(),
);
return Err(OpError::not_found("File not found".to_string()));
}
fs::copy(&from, &to)?;
@ -297,7 +293,7 @@ fn op_stat(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: StatArgs = serde_json::from_value(args)?;
let filename = deno_fs::resolve_from_cwd(Path::new(&args.filename))?;
let lstat = args.lstat;
@ -327,7 +323,7 @@ fn op_realpath(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: RealpathArgs = serde_json::from_value(args)?;
let path = deno_fs::resolve_from_cwd(Path::new(&args.path))?;
@ -359,7 +355,7 @@ fn op_read_dir(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ReadDirArgs = serde_json::from_value(args)?;
let path = deno_fs::resolve_from_cwd(Path::new(&args.path))?;
@ -398,7 +394,7 @@ fn op_rename(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: RenameArgs = serde_json::from_value(args)?;
let oldpath = deno_fs::resolve_from_cwd(Path::new(&args.oldpath))?;
let newpath = deno_fs::resolve_from_cwd(Path::new(&args.newpath))?;
@ -427,7 +423,7 @@ fn op_link(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: LinkArgs = serde_json::from_value(args)?;
let oldname = deno_fs::resolve_from_cwd(Path::new(&args.oldname))?;
let newname = deno_fs::resolve_from_cwd(Path::new(&args.newname))?;
@ -455,7 +451,7 @@ fn op_symlink(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: SymlinkArgs = serde_json::from_value(args)?;
let oldname = deno_fs::resolve_from_cwd(Path::new(&args.oldname))?;
let newname = deno_fs::resolve_from_cwd(Path::new(&args.newname))?;
@ -463,9 +459,7 @@ fn op_symlink(
state.check_write(&newname)?;
// TODO Use type for Windows.
if cfg!(windows) {
return Err(
DenoError::new(ErrorKind::Other, "Not implemented".to_string()).into(),
);
return Err(OpError::other("Not implemented".to_string()));
}
let is_sync = args.promise_id.is_none();
blocking_json(is_sync, move || {
@ -487,7 +481,7 @@ fn op_read_link(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ReadLinkArgs = serde_json::from_value(args)?;
let name = deno_fs::resolve_from_cwd(Path::new(&args.name))?;
@ -515,7 +509,7 @@ fn op_truncate(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: TruncateArgs = serde_json::from_value(args)?;
let filename = deno_fs::resolve_from_cwd(Path::new(&args.name))?;
let len = args.len;
@ -544,7 +538,7 @@ fn op_make_temp_dir(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: MakeTempArgs = serde_json::from_value(args)?;
let dir = args.dir.map(PathBuf::from);
@ -576,7 +570,7 @@ fn op_make_temp_file(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: MakeTempArgs = serde_json::from_value(args)?;
let dir = args.dir.map(PathBuf::from);
@ -617,7 +611,7 @@ fn op_utime(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: Utime = serde_json::from_value(args)?;
state.check_write(Path::new(&args.filename))?;
let is_sync = args.promise_id.is_none();
@ -632,7 +626,7 @@ fn op_cwd(
_state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let path = std::env::current_dir()?;
let path_str = path.into_os_string().into_string().unwrap();
Ok(JsonOp::Sync(json!(path_str)))

View file

@ -1,6 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use crate::deno_error::bad_resource;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use deno_core::*;
@ -70,7 +70,7 @@ pub fn op_fs_events_open(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
#[derive(Deserialize)]
struct OpenArgs {
recursive: bool,
@ -84,7 +84,8 @@ pub fn op_fs_events_open(
let res2 = res.map(FsEvent::from).map_err(ErrBox::from);
let mut sender = sender.lock().unwrap();
futures::executor::block_on(sender.send(res2)).expect("fs events error");
})?;
})
.map_err(ErrBox::from)?;
let recursive_mode = if args.recursive {
RecursiveMode::Recursive
} else {
@ -92,7 +93,7 @@ pub fn op_fs_events_open(
};
for path in &args.paths {
state.check_read(&PathBuf::from(path))?;
watcher.watch(path, recursive_mode)?;
watcher.watch(path, recursive_mode).map_err(ErrBox::from)?;
}
let resource = FsEventsResource { watcher, receiver };
let table = &mut state.borrow_mut().resource_table;
@ -104,7 +105,7 @@ pub fn op_fs_events_poll(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
#[derive(Deserialize)]
struct PollArgs {
rid: u32,
@ -115,13 +116,13 @@ pub fn op_fs_events_poll(
let resource_table = &mut state.borrow_mut().resource_table;
let watcher = resource_table
.get_mut::<FsEventsResource>(rid)
.ok_or_else(bad_resource)?;
.ok_or_else(OpError::bad_resource)?;
watcher
.receiver
.poll_recv(cx)
.map(|maybe_result| match maybe_result {
Some(Ok(value)) => Ok(json!({ "value": value, "done": false })),
Some(Err(err)) => Err(err),
Some(Err(err)) => Err(OpError::from(err)),
None => Ok(json!({ "done": true })),
})
});

View file

@ -1,10 +1,8 @@
use super::dispatch_minimal::MinimalOp;
use crate::deno_error;
use crate::deno_error::bad_resource;
use crate::http_util::HttpBody;
use crate::op_error::OpError;
use crate::ops::minimal_op;
use crate::state::State;
use deno_core::ErrBox;
use deno_core::*;
use futures::future::FutureExt;
use futures::ready;
@ -86,13 +84,13 @@ pub enum StreamResource {
}
/// `DenoAsyncRead` is the same as the `tokio_io::AsyncRead` trait
/// but uses an `ErrBox` error instead of `std::io:Error`
/// but uses an `OpError` error instead of `std::io:Error`
pub trait DenoAsyncRead {
fn poll_read(
&mut self,
cx: &mut Context,
buf: &mut [u8],
) -> Poll<Result<usize, ErrBox>>;
) -> Poll<Result<usize, OpError>>;
}
impl DenoAsyncRead for StreamResource {
@ -100,7 +98,7 @@ impl DenoAsyncRead for StreamResource {
&mut self,
cx: &mut Context,
buf: &mut [u8],
) -> Poll<Result<usize, ErrBox>> {
) -> Poll<Result<usize, OpError>> {
use StreamResource::*;
let mut f: Pin<Box<dyn AsyncRead>> = match self {
FsFile(f) => Box::pin(f),
@ -111,7 +109,7 @@ impl DenoAsyncRead for StreamResource {
ChildStdout(f) => Box::pin(f),
ChildStderr(f) => Box::pin(f),
HttpBody(f) => Box::pin(f),
_ => return Err(bad_resource()).into(),
_ => return Err(OpError::bad_resource()).into(),
};
let v = ready!(f.as_mut().poll_read(cx, buf))?;
@ -158,7 +156,7 @@ impl<T> Future for Read<T>
where
T: AsMut<[u8]> + Unpin,
{
type Output = Result<i32, ErrBox>;
type Output = Result<i32, OpError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let inner = self.get_mut();
@ -170,13 +168,17 @@ where
let resource = state
.resource_table
.get_mut::<StreamResource>(inner.rid)
.ok_or_else(bad_resource)?;
.ok_or_else(OpError::bad_resource)?;
let nread = ready!(resource.poll_read(cx, &mut inner.buf.as_mut()[..]))?;
inner.io_state = IoState::Done;
Poll::Ready(Ok(nread as i32))
}
}
fn no_buffer_specified() -> OpError {
OpError::type_error("no buffer specified".to_string())
}
pub fn op_read(
state: &State,
rid: i32,
@ -184,10 +186,7 @@ pub fn op_read(
) -> Pin<Box<MinimalOp>> {
debug!("read rid={}", rid);
let zero_copy = match zero_copy {
None => {
return futures::future::err(deno_error::no_buffer_specified())
.boxed_local()
}
None => return futures::future::err(no_buffer_specified()).boxed_local(),
Some(buf) => buf,
};
@ -196,17 +195,17 @@ pub fn op_read(
}
/// `DenoAsyncWrite` is the same as the `tokio_io::AsyncWrite` trait
/// but uses an `ErrBox` error instead of `std::io:Error`
/// but uses an `OpError` error instead of `std::io:Error`
pub trait DenoAsyncWrite {
fn poll_write(
&mut self,
cx: &mut Context,
buf: &[u8],
) -> Poll<Result<usize, ErrBox>>;
) -> Poll<Result<usize, OpError>>;
fn poll_close(&mut self, cx: &mut Context) -> Poll<Result<(), ErrBox>>;
fn poll_close(&mut self, cx: &mut Context) -> Poll<Result<(), OpError>>;
fn poll_flush(&mut self, cx: &mut Context) -> Poll<Result<(), ErrBox>>;
fn poll_flush(&mut self, cx: &mut Context) -> Poll<Result<(), OpError>>;
}
impl DenoAsyncWrite for StreamResource {
@ -214,7 +213,7 @@ impl DenoAsyncWrite for StreamResource {
&mut self,
cx: &mut Context,
buf: &[u8],
) -> Poll<Result<usize, ErrBox>> {
) -> Poll<Result<usize, OpError>> {
use StreamResource::*;
let mut f: Pin<Box<dyn AsyncWrite>> = match self {
FsFile(f) => Box::pin(f),
@ -224,14 +223,14 @@ impl DenoAsyncWrite for StreamResource {
ClientTlsStream(f) => Box::pin(f),
ServerTlsStream(f) => Box::pin(f),
ChildStdin(f) => Box::pin(f),
_ => return Err(bad_resource()).into(),
_ => return Err(OpError::bad_resource()).into(),
};
let v = ready!(f.as_mut().poll_write(cx, buf))?;
Ok(v).into()
}
fn poll_flush(&mut self, cx: &mut Context) -> Poll<Result<(), ErrBox>> {
fn poll_flush(&mut self, cx: &mut Context) -> Poll<Result<(), OpError>> {
use StreamResource::*;
let mut f: Pin<Box<dyn AsyncWrite>> = match self {
FsFile(f) => Box::pin(f),
@ -241,14 +240,14 @@ impl DenoAsyncWrite for StreamResource {
ClientTlsStream(f) => Box::pin(f),
ServerTlsStream(f) => Box::pin(f),
ChildStdin(f) => Box::pin(f),
_ => return Err(bad_resource()).into(),
_ => return Err(OpError::bad_resource()).into(),
};
ready!(f.as_mut().poll_flush(cx))?;
Ok(()).into()
}
fn poll_close(&mut self, _cx: &mut Context) -> Poll<Result<(), ErrBox>> {
fn poll_close(&mut self, _cx: &mut Context) -> Poll<Result<(), OpError>> {
unimplemented!()
}
}
@ -281,12 +280,12 @@ where
}
/// This is almost the same implementation as in tokio, difference is
/// that error type is `ErrBox` instead of `std::io::Error`.
/// that error type is `OpError` instead of `std::io::Error`.
impl<T> Future for Write<T>
where
T: AsRef<[u8]> + Unpin,
{
type Output = Result<i32, ErrBox>;
type Output = Result<i32, OpError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let inner = self.get_mut();
@ -299,7 +298,7 @@ where
let resource = state
.resource_table
.get_mut::<StreamResource>(inner.rid)
.ok_or_else(bad_resource)?;
.ok_or_else(OpError::bad_resource)?;
let nwritten = ready!(resource.poll_write(cx, inner.buf.as_ref()))?;
inner.io_state = IoState::Flush;
@ -315,7 +314,7 @@ where
let resource = state
.resource_table
.get_mut::<StreamResource>(inner.rid)
.ok_or_else(bad_resource)?;
.ok_or_else(OpError::bad_resource)?;
ready!(resource.poll_flush(cx))?;
inner.io_state = IoState::Done;
}
@ -331,10 +330,7 @@ pub fn op_write(
) -> Pin<Box<MinimalOp>> {
debug!("write rid={}", rid);
let zero_copy = match zero_copy {
None => {
return futures::future::err(deno_error::no_buffer_specified())
.boxed_local()
}
None => return futures::future::err(no_buffer_specified()).boxed_local(),
Some(buf) => buf,
};

View file

@ -1,7 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use super::io::StreamResource;
use crate::deno_error::bad_resource;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::resolve_addr::resolve_addr;
use crate::state::State;
@ -52,7 +52,7 @@ pub struct Accept<'a> {
}
impl Future for Accept<'_> {
type Output = Result<(TcpStream, SocketAddr), ErrBox>;
type Output = Result<(TcpStream, SocketAddr), OpError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let inner = self.get_mut();
@ -64,17 +64,11 @@ impl Future for Accept<'_> {
let listener_resource = state
.resource_table
.get_mut::<TcpListenerResource>(inner.rid)
.ok_or_else(|| {
let e = std::io::Error::new(
std::io::ErrorKind::Other,
"Listener has been closed",
);
ErrBox::from(e)
})?;
.ok_or_else(|| OpError::other("Listener has been closed".to_string()))?;
let listener = &mut listener_resource.listener;
match listener.poll_accept(cx).map_err(ErrBox::from) {
match listener.poll_accept(cx).map_err(OpError::from) {
Poll::Ready(Ok((stream, addr))) => {
listener_resource.untrack_task();
inner.accept_state = AcceptState::Done;
@ -102,7 +96,7 @@ fn op_accept(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: AcceptArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let state_ = state.clone();
@ -111,7 +105,7 @@ fn op_accept(
state
.resource_table
.get::<TcpListenerResource>(rid)
.ok_or_else(bad_resource)?;
.ok_or_else(OpError::bad_resource)?;
}
let op = async move {
@ -147,7 +141,7 @@ pub struct Receive<'a> {
}
impl Future for Receive<'_> {
type Output = Result<(usize, SocketAddr), ErrBox>;
type Output = Result<(usize, SocketAddr), OpError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let inner = self.get_mut();
@ -155,19 +149,13 @@ impl Future for Receive<'_> {
let resource = state
.resource_table
.get_mut::<UdpSocketResource>(inner.rid)
.ok_or_else(|| {
let e = std::io::Error::new(
std::io::ErrorKind::Other,
"Socket has been closed",
);
ErrBox::from(e)
})?;
.ok_or_else(|| OpError::other("Socket has been closed".to_string()))?;
let socket = &mut resource.socket;
socket
.poll_recv_from(cx, &mut inner.buf)
.map_err(ErrBox::from)
.map_err(OpError::from)
}
}
@ -184,7 +172,7 @@ fn op_receive(
state: &State,
args: Value,
zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
assert!(zero_copy.is_some());
let buf = zero_copy.unwrap();
@ -221,7 +209,7 @@ fn op_send(
state: &State,
args: Value,
zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
assert!(zero_copy.is_some());
let buf = zero_copy.unwrap();
@ -237,13 +225,7 @@ fn op_send(
let resource = state
.resource_table
.get_mut::<UdpSocketResource>(rid)
.ok_or_else(|| {
let e = std::io::Error::new(
std::io::ErrorKind::Other,
"Socket has been closed",
);
ErrBox::from(e)
})?;
.ok_or_else(|| OpError::other("Socket has been closed".to_string()))?;
let socket = &mut resource.socket;
let addr = resolve_addr(&args.hostname, args.port).await?;
@ -266,7 +248,7 @@ fn op_connect(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ConnectArgs = serde_json::from_value(args)?;
assert_eq!(args.transport, "tcp"); // TODO Support others.
let state_ = state.clone();
@ -309,7 +291,7 @@ fn op_shutdown(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ShutdownArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
@ -325,12 +307,12 @@ fn op_shutdown(
let resource = state
.resource_table
.get_mut::<StreamResource>(rid)
.ok_or_else(bad_resource)?;
.ok_or_else(OpError::bad_resource)?;
match resource {
StreamResource::TcpStream(ref mut stream) => {
TcpStream::shutdown(stream, shutdown_mode).map_err(ErrBox::from)?;
TcpStream::shutdown(stream, shutdown_mode).map_err(OpError::from)?;
}
_ => return Err(bad_resource()),
_ => return Err(OpError::bad_resource()),
}
Ok(JsonOp::Sync(json!({})))
@ -361,17 +343,13 @@ impl TcpListenerResource {
/// can be notified when listener is closed.
///
/// Throws an error if another task is already tracked.
pub fn track_task(&mut self, cx: &Context) -> Result<(), ErrBox> {
pub fn track_task(&mut self, cx: &Context) -> Result<(), OpError> {
// Currently, we only allow tracking a single accept task for a listener.
// This might be changed in the future with multiple workers.
// Caveat: TcpListener by itself also only tracks an accept task at a time.
// See https://github.com/tokio-rs/tokio/issues/846#issuecomment-454208883
if self.waker.is_some() {
let e = std::io::Error::new(
std::io::ErrorKind::Other,
"Another accept task is ongoing",
);
return Err(ErrBox::from(e));
return Err(OpError::other("Another accept task is ongoing".to_string()));
}
let waker = futures::task::AtomicWaker::new();
@ -403,7 +381,7 @@ struct UdpSocketResource {
fn listen_tcp(
state: &State,
addr: SocketAddr,
) -> Result<(u32, SocketAddr), ErrBox> {
) -> Result<(u32, SocketAddr), OpError> {
let mut state = state.borrow_mut();
let listener = futures::executor::block_on(TcpListener::bind(&addr))?;
let local_addr = listener.local_addr()?;
@ -422,7 +400,7 @@ fn listen_tcp(
fn listen_udp(
state: &State,
addr: SocketAddr,
) -> Result<(u32, SocketAddr), ErrBox> {
) -> Result<(u32, SocketAddr), OpError> {
let mut state = state.borrow_mut();
let socket = futures::executor::block_on(UdpSocket::bind(&addr))?;
let local_addr = socket.local_addr()?;
@ -438,7 +416,7 @@ fn op_listen(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ListenArgs = serde_json::from_value(args)?;
assert!(args.transport == "tcp" || args.transport == "udp");

View file

@ -1,5 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use atty;
@ -31,7 +32,7 @@ fn op_get_dir(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
state.check_env()?;
let args: GetDirArgs = serde_json::from_value(args)?;
@ -52,17 +53,20 @@ fn op_get_dir(
"template" => dirs::template_dir(),
"video" => dirs::video_dir(),
_ => {
return Err(ErrBox::from(Error::new(
ErrorKind::InvalidInput,
format!("Invalid dir type `{}`", args.kind.as_str()),
)))
return Err(
Error::new(
ErrorKind::InvalidInput,
format!("Invalid dir type `{}`", args.kind.as_str()),
)
.into(),
)
}
};
if path == None {
Err(ErrBox::from(Error::new(
ErrorKind::NotFound,
format!("Could not get user {} directory.", args.kind.as_str()),
Err(OpError::not_found(format!(
"Could not get user {} directory.",
args.kind.as_str()
)))
} else {
Ok(JsonOp::Sync(json!(path
@ -77,7 +81,7 @@ fn op_exec_path(
state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
state.check_env()?;
let current_exe = env::current_exe().unwrap();
// Now apply URL parser to current exe to get fully resolved path, otherwise
@ -97,7 +101,7 @@ fn op_set_env(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: SetEnv = serde_json::from_value(args)?;
state.check_env()?;
env::set_var(args.key, args.value);
@ -108,7 +112,7 @@ fn op_env(
state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
state.check_env()?;
let v = env::vars().collect::<HashMap<String, String>>();
Ok(JsonOp::Sync(json!(v)))
@ -123,7 +127,7 @@ fn op_get_env(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: GetEnv = serde_json::from_value(args)?;
state.check_env()?;
let r = match env::var(args.key) {
@ -142,7 +146,7 @@ fn op_exit(
_s: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: Exit = serde_json::from_value(args)?;
std::process::exit(args.code)
}
@ -151,7 +155,7 @@ fn op_is_tty(
_s: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
Ok(JsonOp::Sync(json!({
"stdin": atty::is(atty::Stream::Stdin),
"stdout": atty::is(atty::Stream::Stdout),
@ -163,7 +167,7 @@ fn op_loadavg(
state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
state.check_env()?;
match sys_info::loadavg() {
Ok(loadavg) => Ok(JsonOp::Sync(json!([
@ -179,7 +183,7 @@ fn op_hostname(
state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
state.check_env()?;
let hostname = sys_info::hostname().unwrap_or_else(|_| "".to_owned());
Ok(JsonOp::Sync(json!(hostname)))

View file

@ -1,7 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use crate::deno_error::other_error;
use crate::fs as deno_fs;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use deno_core::*;
@ -41,7 +41,7 @@ pub fn op_query_permission(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: PermissionArgs = serde_json::from_value(args)?;
let state = state.borrow();
let resolved_path = args.path.as_ref().map(String::as_str).map(resolve_path);
@ -57,7 +57,7 @@ pub fn op_revoke_permission(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: PermissionArgs = serde_json::from_value(args)?;
let mut state = state.borrow_mut();
let permissions = &mut state.permissions;
@ -84,7 +84,7 @@ pub fn op_request_permission(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: PermissionArgs = serde_json::from_value(args)?;
let mut state = state.borrow_mut();
let permissions = &mut state.permissions;
@ -101,7 +101,7 @@ pub fn op_request_permission(
"env" => Ok(permissions.request_env()),
"plugin" => Ok(permissions.request_plugin()),
"hrtime" => Ok(permissions.request_hrtime()),
n => Err(other_error(format!("No such permission name: {}", n))),
n => Err(OpError::other(format!("No such permission name: {}", n))),
}?;
Ok(JsonOp::Sync(json!({ "state": perm.to_string() })))
}

View file

@ -1,5 +1,6 @@
use super::dispatch_json::{Deserialize, JsonOp, Value};
use crate::fs as deno_fs;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use deno_core::*;
@ -19,10 +20,10 @@ pub fn init(i: &mut Isolate, s: &State, r: Rc<deno_core::OpRegistry>) {
);
}
fn open_plugin<P: AsRef<OsStr>>(lib_path: P) -> Result<Library, ErrBox> {
fn open_plugin<P: AsRef<OsStr>>(lib_path: P) -> Result<Library, OpError> {
debug!("Loading Plugin: {:#?}", lib_path.as_ref());
Library::open(lib_path).map_err(ErrBox::from)
Library::open(lib_path).map_err(OpError::from)
}
struct PluginResource {
@ -55,7 +56,7 @@ pub fn op_open_plugin(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: OpenPluginArgs = serde_json::from_value(args)?;
let filename = deno_fs::resolve_from_cwd(Path::new(&args.filename))?;

View file

@ -1,7 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use super::io::StreamResource;
use crate::deno_error::bad_resource;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::signal::kill;
use crate::state::State;
@ -30,15 +30,15 @@ pub fn init(i: &mut Isolate, s: &State) {
i.register_op("kill", s.core_op(json_op(s.stateful_op(op_kill))));
}
fn clone_file(rid: u32, state: &State) -> Result<std::fs::File, ErrBox> {
fn clone_file(rid: u32, state: &State) -> Result<std::fs::File, OpError> {
let mut state = state.borrow_mut();
let repr = state
.resource_table
.get_mut::<StreamResource>(rid)
.ok_or_else(bad_resource)?;
.ok_or_else(OpError::bad_resource)?;
let file = match repr {
StreamResource::FsFile(ref mut file) => file,
_ => return Err(bad_resource()),
_ => return Err(OpError::bad_resource()),
};
let tokio_file = futures::executor::block_on(file.try_clone())?;
let std_file = futures::executor::block_on(tokio_file.into_std());
@ -76,7 +76,7 @@ fn op_run(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let run_args: RunArgs = serde_json::from_value(args)?;
state.check_run()?;
@ -182,7 +182,7 @@ pub struct ChildStatus {
}
impl Future for ChildStatus {
type Output = Result<ExitStatus, ErrBox>;
type Output = Result<ExitStatus, OpError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let inner = self.get_mut();
@ -190,9 +190,9 @@ impl Future for ChildStatus {
let child_resource = state
.resource_table
.get_mut::<ChildResource>(inner.rid)
.ok_or_else(bad_resource)?;
.ok_or_else(OpError::bad_resource)?;
let child = &mut child_resource.child;
child.map_err(ErrBox::from).poll_unpin(cx)
child.map_err(OpError::from).poll_unpin(cx)
}
}
@ -206,7 +206,7 @@ fn op_run_status(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: RunStatusArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
@ -251,7 +251,7 @@ fn op_kill(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
state.check_run()?;
let args: KillArgs = serde_json::from_value(args)?;

View file

@ -1,5 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{JsonOp, Value};
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use deno_core::*;
@ -17,7 +18,7 @@ fn op_get_random_values(
state: &State,
_args: Value,
zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
assert!(zero_copy.is_some());
if let Some(ref mut seeded_rng) = state.borrow_mut().seeded_rng {

View file

@ -1,6 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{blocking_json, Deserialize, JsonOp, Value};
use crate::deno_error::bad_resource;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::repl;
use crate::repl::Repl;
@ -32,7 +32,7 @@ fn op_repl_start(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ReplStartArgs = serde_json::from_value(args)?;
debug!("op_repl_start {}", args.history_file);
@ -55,7 +55,7 @@ fn op_repl_readline(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ReplReadlineArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let prompt = args.prompt;
@ -64,7 +64,7 @@ fn op_repl_readline(
let resource = state
.resource_table
.get::<ReplResource>(rid)
.ok_or_else(bad_resource)?;
.ok_or_else(OpError::bad_resource)?;
let repl = resource.0.clone();
blocking_json(false, move || {

View file

@ -1,5 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{JsonOp, Value};
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use deno_core::*;
@ -12,7 +13,7 @@ fn op_resources(
state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let state = state.borrow();
let serialized_resources = state.resource_table.entries();
Ok(JsonOp::Sync(json!(serialized_resources)))

View file

@ -2,6 +2,7 @@
use super::dispatch_json::{JsonOp, Value};
use crate::colors;
use crate::fs as deno_fs;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use crate::version;
@ -28,7 +29,7 @@ fn op_start(
state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let state = state.borrow();
let gs = &state.global_state;
@ -53,7 +54,7 @@ fn op_metrics(
state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let state = state.borrow();
let m = &state.metrics;

View file

@ -2,6 +2,7 @@
use super::dispatch_json::{Deserialize, JsonOp, Value};
use crate::compilers::runtime_compile_async;
use crate::compilers::runtime_transpile_async;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use deno_core::*;
@ -25,7 +26,7 @@ fn op_compile(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: CompileArgs = serde_json::from_value(args)?;
Ok(JsonOp::Async(runtime_compile_async(
state.borrow().global_state.clone(),
@ -46,7 +47,7 @@ fn op_transpile(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: TranspileArgs = serde_json::from_value(args)?;
Ok(JsonOp::Async(runtime_transpile_async(
state.borrow().global_state.clone(),

View file

@ -1,5 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{JsonOp, Value};
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use deno_core::*;
@ -7,8 +8,6 @@ use deno_core::*;
#[cfg(unix)]
use super::dispatch_json::Deserialize;
#[cfg(unix)]
use crate::deno_error::bad_resource;
#[cfg(unix)]
use futures::future::{poll_fn, FutureExt};
#[cfg(unix)]
use serde_json;
@ -54,7 +53,7 @@ fn op_signal_bind(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: BindSignalArgs = serde_json::from_value(args)?;
let mut state = state.borrow_mut();
let rid = state.resource_table.add(
@ -74,7 +73,7 @@ fn op_signal_poll(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: SignalArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let state_ = state.clone();
@ -99,7 +98,7 @@ pub fn op_signal_unbind(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: SignalArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let mut state = state.borrow_mut();
@ -111,7 +110,10 @@ pub fn op_signal_unbind(
waker.clone().wake();
}
}
state.resource_table.close(rid).ok_or_else(bad_resource)?;
state
.resource_table
.close(rid)
.ok_or_else(OpError::bad_resource)?;
Ok(JsonOp::Sync(json!({})))
}
@ -120,7 +122,7 @@ pub fn op_signal_bind(
_state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
unimplemented!();
}
@ -129,7 +131,7 @@ fn op_signal_unbind(
_state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
unimplemented!();
}
@ -138,6 +140,6 @@ fn op_signal_poll(
_state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
unimplemented!();
}

View file

@ -1,5 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use deno_core::*;
@ -24,7 +25,7 @@ fn op_global_timer_stop(
state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let mut state = state.borrow_mut();
state.global_timer.cancel();
Ok(JsonOp::Sync(json!({})))
@ -39,7 +40,7 @@ fn op_global_timer(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: GlobalTimerArgs = serde_json::from_value(args)?;
let val = args.timeout;
@ -61,7 +62,7 @@ fn op_now(
state: &State,
_args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let state = state.borrow();
let seconds = state.start_time.elapsed().as_secs();
let mut subsec_nanos = state.start_time.elapsed().subsec_nanos();

View file

@ -1,9 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use super::io::StreamResource;
use crate::deno_error::bad_resource;
use crate::deno_error::DenoError;
use crate::deno_error::ErrorKind;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::resolve_addr::resolve_addr;
use crate::state::State;
@ -63,7 +61,7 @@ pub fn op_connect_tls(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ConnectTLSArgs = serde_json::from_value(args)?;
let cert_file = args.cert_file.clone();
let state_ = state.clone();
@ -118,35 +116,31 @@ pub fn op_connect_tls(
Ok(JsonOp::Async(op.boxed_local()))
}
fn load_certs(path: &str) -> Result<Vec<Certificate>, ErrBox> {
fn load_certs(path: &str) -> Result<Vec<Certificate>, OpError> {
let cert_file = File::open(path)?;
let reader = &mut BufReader::new(cert_file);
let certs = certs(reader).map_err(|_| {
DenoError::new(ErrorKind::Other, "Unable to decode certificate".to_string())
})?;
let certs = certs(reader)
.map_err(|_| OpError::other("Unable to decode certificate".to_string()))?;
if certs.is_empty() {
let e = DenoError::new(
ErrorKind::Other,
"No certificates found in cert file".to_string(),
);
return Err(ErrBox::from(e));
let e = OpError::other("No certificates found in cert file".to_string());
return Err(e);
}
Ok(certs)
}
fn key_decode_err() -> DenoError {
DenoError::new(ErrorKind::Other, "Unable to decode key".to_string())
fn key_decode_err() -> OpError {
OpError::other("Unable to decode key".to_string())
}
fn key_not_found_err() -> DenoError {
DenoError::new(ErrorKind::Other, "No keys found in key file".to_string())
fn key_not_found_err() -> OpError {
OpError::other("No keys found in key file".to_string())
}
/// Starts with -----BEGIN RSA PRIVATE KEY-----
fn load_rsa_keys(path: &str) -> Result<Vec<PrivateKey>, ErrBox> {
fn load_rsa_keys(path: &str) -> Result<Vec<PrivateKey>, OpError> {
let key_file = File::open(path)?;
let reader = &mut BufReader::new(key_file);
let keys = rsa_private_keys(reader).map_err(|_| key_decode_err())?;
@ -154,14 +148,14 @@ fn load_rsa_keys(path: &str) -> Result<Vec<PrivateKey>, ErrBox> {
}
/// Starts with -----BEGIN PRIVATE KEY-----
fn load_pkcs8_keys(path: &str) -> Result<Vec<PrivateKey>, ErrBox> {
fn load_pkcs8_keys(path: &str) -> Result<Vec<PrivateKey>, OpError> {
let key_file = File::open(path)?;
let reader = &mut BufReader::new(key_file);
let keys = pkcs8_private_keys(reader).map_err(|_| key_decode_err())?;
Ok(keys)
}
fn load_keys(path: &str) -> Result<Vec<PrivateKey>, ErrBox> {
fn load_keys(path: &str) -> Result<Vec<PrivateKey>, OpError> {
let path = path.to_string();
let mut keys = load_rsa_keys(&path)?;
@ -170,7 +164,7 @@ fn load_keys(path: &str) -> Result<Vec<PrivateKey>, ErrBox> {
}
if keys.is_empty() {
return Err(ErrBox::from(key_not_found_err()));
return Err(key_not_found_err());
}
Ok(keys)
@ -195,17 +189,13 @@ impl TlsListenerResource {
/// can be notified when listener is closed.
///
/// Throws an error if another task is already tracked.
pub fn track_task(&mut self, cx: &Context) -> Result<(), ErrBox> {
pub fn track_task(&mut self, cx: &Context) -> Result<(), OpError> {
// Currently, we only allow tracking a single accept task for a listener.
// This might be changed in the future with multiple workers.
// Caveat: TcpListener by itself also only tracks an accept task at a time.
// See https://github.com/tokio-rs/tokio/issues/846#issuecomment-454208883
if self.waker.is_some() {
let e = std::io::Error::new(
std::io::ErrorKind::Other,
"Another accept task is ongoing",
);
return Err(ErrBox::from(e));
return Err(OpError::other("Another accept task is ongoing".to_string()));
}
let waker = futures::task::AtomicWaker::new();
@ -244,7 +234,7 @@ fn op_listen_tls(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: ListenTlsArgs = serde_json::from_value(args)?;
assert_eq!(args.transport, "tcp");
@ -308,7 +298,7 @@ pub struct AcceptTls {
}
impl Future for AcceptTls {
type Output = Result<(TcpStream, SocketAddr), ErrBox>;
type Output = Result<(TcpStream, SocketAddr), OpError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let inner = self.get_mut();
@ -320,17 +310,11 @@ impl Future for AcceptTls {
let listener_resource = state
.resource_table
.get_mut::<TlsListenerResource>(inner.rid)
.ok_or_else(|| {
let e = std::io::Error::new(
std::io::ErrorKind::Other,
"Listener has been closed",
);
ErrBox::from(e)
})?;
.ok_or_else(|| OpError::other("Listener has been closed".to_string()))?;
let listener = &mut listener_resource.listener;
match listener.poll_accept(cx).map_err(ErrBox::from) {
match listener.poll_accept(cx).map_err(OpError::from) {
Poll::Ready(Ok((stream, addr))) => {
listener_resource.untrack_task();
inner.accept_state = AcceptTlsState::Done;
@ -358,7 +342,7 @@ fn op_accept_tls(
state: &State,
args: Value,
_zero_copy: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: AcceptTlsArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let state = state.clone();
@ -371,7 +355,7 @@ fn op_accept_tls(
let resource = state
.resource_table
.get::<TlsListenerResource>(rid)
.ok_or_else(bad_resource)
.ok_or_else(OpError::bad_resource)
.expect("Can't find tls listener");
resource.tls_acceptor.clone()
};

View file

@ -1,5 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{JsonOp, Value};
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::state::State;
use crate::worker::WorkerEvent;
@ -13,17 +14,17 @@ use std::convert::From;
pub fn web_worker_op<D>(
sender: mpsc::Sender<WorkerEvent>,
dispatcher: D,
) -> impl Fn(Value, Option<ZeroCopyBuf>) -> Result<JsonOp, ErrBox>
) -> impl Fn(Value, Option<ZeroCopyBuf>) -> Result<JsonOp, OpError>
where
D: Fn(
&mpsc::Sender<WorkerEvent>,
Value,
Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox>,
) -> Result<JsonOp, OpError>,
{
move |args: Value, zero_copy: Option<ZeroCopyBuf>| -> Result<JsonOp, ErrBox> {
dispatcher(&sender, args, zero_copy)
}
move |args: Value,
zero_copy: Option<ZeroCopyBuf>|
-> Result<JsonOp, OpError> { dispatcher(&sender, args, zero_copy) }
}
pub fn init(i: &mut Isolate, s: &State, sender: &mpsc::Sender<WorkerEvent>) {
@ -45,7 +46,7 @@ fn op_worker_post_message(
sender: &mpsc::Sender<WorkerEvent>,
_args: Value,
data: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let d = Vec::from(data.unwrap().as_ref()).into_boxed_slice();
let mut sender = sender.clone();
let fut = sender.send(WorkerEvent::Message(d));
@ -58,7 +59,7 @@ fn op_worker_close(
sender: &mpsc::Sender<WorkerEvent>,
_args: Value,
_data: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let mut sender = sender.clone();
sender.close_channel();
Ok(JsonOp::Sync(json!({})))

View file

@ -1,10 +1,9 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use super::dispatch_json::{Deserialize, JsonOp, Value};
use crate::deno_error::DenoError;
use crate::deno_error::ErrorKind;
use crate::fmt_errors::JSError;
use crate::futures::SinkExt;
use crate::global_state::GlobalState;
use crate::op_error::OpError;
use crate::ops::json_op;
use crate::permissions::DenoPermissions;
use crate::startup_data;
@ -147,7 +146,7 @@ fn op_create_worker(
state: &State,
args: Value,
_data: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: CreateWorkerArgs = serde_json::from_value(args)?;
let specifier = args.specifier.clone();
@ -175,7 +174,8 @@ fn op_create_worker(
module_specifier,
has_source_code,
source_code,
)?;
)
.map_err(|e| OpError::other(e.to_string()))?;
// At this point all interactions with worker happen using thread
// safe handler returned from previous function call
let mut parent_state = parent_state.borrow_mut();
@ -197,7 +197,7 @@ fn op_host_terminate_worker(
state: &State,
args: Value,
_data: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: WorkerArgs = serde_json::from_value(args)?;
let id = args.id as u32;
let mut state = state.borrow_mut();
@ -242,7 +242,7 @@ fn op_host_get_message(
state: &State,
args: Value,
_data: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: WorkerArgs = serde_json::from_value(args)?;
let id = args.id as u32;
let worker_handle = {
@ -274,7 +274,7 @@ fn op_host_post_message(
state: &State,
args: Value,
data: Option<ZeroCopyBuf>,
) -> Result<JsonOp, ErrBox> {
) -> Result<JsonOp, OpError> {
let args: WorkerArgs = serde_json::from_value(args)?;
let id = args.id as u32;
let msg = Vec::from(data.unwrap().as_ref()).into_boxed_slice();
@ -285,7 +285,7 @@ fn op_host_post_message(
state.workers.get(&id).expect("No worker handle found");
let fut = worker_handle
.post_message(msg)
.map_err(|e| DenoError::new(ErrorKind::Other, e.to_string()));
.map_err(|e| OpError::other(e.to_string()));
futures::executor::block_on(fut)?;
Ok(JsonOp::Sync(json!({})))
}

View file

@ -1,11 +1,9 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::deno_error::{other_error, permission_denied_msg};
use crate::deno_error::{DenoError, ErrorKind};
use crate::flags::DenoFlags;
use crate::op_error::OpError;
use ansi_term::Style;
#[cfg(not(test))]
use atty;
use deno_core::ErrBox;
use log;
use std::collections::HashSet;
use std::fmt;
@ -30,13 +28,13 @@ pub enum PermissionState {
impl PermissionState {
/// Checks the permission state and returns the result.
pub fn check(self, msg: &str, flag_name: &str) -> Result<(), ErrBox> {
pub fn check(self, msg: &str, flag_name: &str) -> Result<(), OpError> {
if self == PermissionState::Allow {
log_perm_access(msg);
return Ok(());
}
let m = format!("{}, run again with the {} flag", msg, flag_name);
Err(permission_denied_msg(m))
Err(OpError::permission_denied(m))
}
pub fn is_allow(self) -> bool {
self == PermissionState::Allow
@ -130,7 +128,7 @@ impl DenoPermissions {
}
}
pub fn check_run(&self) -> Result<(), ErrBox> {
pub fn check_run(&self) -> Result<(), OpError> {
self
.allow_run
.check("access to run a subprocess", "--allow-run")
@ -143,7 +141,7 @@ impl DenoPermissions {
self.allow_read
}
pub fn check_read(&self, path: &Path) -> Result<(), ErrBox> {
pub fn check_read(&self, path: &Path) -> Result<(), OpError> {
self.get_state_read(&Some(path)).check(
&format!("read access to \"{}\"", path.display()),
"--allow-read",
@ -157,7 +155,7 @@ impl DenoPermissions {
self.allow_write
}
pub fn check_write(&self, path: &Path) -> Result<(), ErrBox> {
pub fn check_write(&self, path: &Path) -> Result<(), OpError> {
self.get_state_write(&Some(path)).check(
&format!("write access to \"{}\"", path.display()),
"--allow-write",
@ -174,41 +172,41 @@ impl DenoPermissions {
fn get_state_net_url(
&self,
url: &Option<&str>,
) -> Result<PermissionState, ErrBox> {
) -> Result<PermissionState, OpError> {
if url.is_none() {
return Ok(self.allow_net);
}
let url: &str = url.unwrap();
// If url is invalid, then throw a TypeError.
let parsed = Url::parse(url).map_err(ErrBox::from)?;
let parsed = Url::parse(url).map_err(OpError::from)?;
Ok(
self.get_state_net(&format!("{}", parsed.host().unwrap()), parsed.port()),
)
}
pub fn check_net(&self, hostname: &str, port: u16) -> Result<(), ErrBox> {
pub fn check_net(&self, hostname: &str, port: u16) -> Result<(), OpError> {
self.get_state_net(hostname, Some(port)).check(
&format!("network access to \"{}:{}\"", hostname, port),
"--allow-net",
)
}
pub fn check_net_url(&self, url: &url::Url) -> Result<(), ErrBox> {
let host = url.host_str().ok_or_else(|| {
DenoError::new(ErrorKind::URIError, "missing host".to_owned())
})?;
pub fn check_net_url(&self, url: &url::Url) -> Result<(), OpError> {
let host = url
.host_str()
.ok_or_else(|| OpError::uri_error("missing host".to_owned()))?;
self
.get_state_net(host, url.port())
.check(&format!("network access to \"{}\"", url), "--allow-net")
}
pub fn check_env(&self) -> Result<(), ErrBox> {
pub fn check_env(&self) -> Result<(), OpError> {
self
.allow_env
.check("access to environment variables", "--allow-env")
}
pub fn check_plugin(&self, path: &Path) -> Result<(), ErrBox> {
pub fn check_plugin(&self, path: &Path) -> Result<(), OpError> {
self.allow_plugin.check(
&format!("access to open a plugin: {}", path.display()),
"--allow-plugin",
@ -248,7 +246,7 @@ impl DenoPermissions {
pub fn request_net(
&mut self,
url: &Option<&str>,
) -> Result<PermissionState, ErrBox> {
) -> Result<PermissionState, OpError> {
if self.get_state_net_url(url)? == PermissionState::Ask {
return Ok(self.allow_net.request(&match url {
None => "Deno requests network access.".to_string(),
@ -279,7 +277,7 @@ impl DenoPermissions {
name: &str,
url: &Option<&str>,
path: &Option<&Path>,
) -> Result<PermissionState, ErrBox> {
) -> Result<PermissionState, OpError> {
match name {
"run" => Ok(self.allow_run),
"read" => Ok(self.get_state_read(path)),
@ -288,7 +286,7 @@ impl DenoPermissions {
"env" => Ok(self.allow_env),
"plugin" => Ok(self.allow_plugin),
"hrtime" => Ok(self.allow_hrtime),
n => Err(other_error(format!("No such permission name: {}", n))),
n => Err(OpError::other(format!("No such permission name: {}", n))),
}
}
}

View file

@ -1,5 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::deno_dir::DenoDir;
use crate::op_error::OpError;
use deno_core::ErrBox;
use rustyline;
use std::fs;
@ -88,7 +89,7 @@ impl Repl {
})
}
pub fn readline(&mut self, prompt: &str) -> Result<String, ErrBox> {
pub fn readline(&mut self, prompt: &str) -> Result<String, OpError> {
self
.editor
.readline(&prompt)
@ -96,7 +97,7 @@ impl Repl {
self.editor.add_history_entry(line.clone());
line
})
.map_err(ErrBox::from)
.map_err(OpError::from)
// Forward error to TS side for processing
}
}

View file

@ -1,5 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use deno_core::ErrBox;
use crate::op_error::OpError;
use std::future::Future;
use std::net::SocketAddr;
use std::net::ToSocketAddrs;
@ -21,7 +21,7 @@ pub struct ResolveAddrFuture {
}
impl Future for ResolveAddrFuture {
type Output = Result<SocketAddr, ErrBox>;
type Output = Result<SocketAddr, OpError>;
fn poll(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Self::Output> {
let inner = self.get_mut();
@ -45,7 +45,7 @@ impl Future for ResolveAddrFuture {
addr
};
let addr_port_pair = (addr, inner.port);
let r = addr_port_pair.to_socket_addrs().map_err(ErrBox::from);
let r = addr_port_pair.to_socket_addrs().map_err(OpError::from);
Poll::Ready(r.and_then(|mut iter| match iter.next() {
Some(a) => Ok(a),

View file

@ -1,16 +1,16 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use deno_core::ErrBox;
use crate::op_error::OpError;
#[cfg(unix)]
pub fn kill(pid: i32, signo: i32) -> Result<(), ErrBox> {
pub fn kill(pid: i32, signo: i32) -> Result<(), OpError> {
use nix::sys::signal::{kill as unix_kill, Signal};
use nix::unistd::Pid;
let sig = Signal::from_c_int(signo)?;
unix_kill(Pid::from_raw(pid), Option::Some(sig)).map_err(ErrBox::from)
unix_kill(Pid::from_raw(pid), Option::Some(sig)).map_err(OpError::from)
}
#[cfg(not(unix))]
pub fn kill(_pid: i32, _signal: i32) -> Result<(), ErrBox> {
pub fn kill(_pid: i32, _signal: i32) -> Result<(), OpError> {
// NOOP
// TODO: implement this for windows
Ok(())

View file

@ -1,10 +1,10 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::compilers::TargetLib;
use crate::deno_error::permission_denied;
use crate::global_state::GlobalState;
use crate::global_timer::GlobalTimer;
use crate::import_map::ImportMap;
use crate::metrics::Metrics;
use crate::op_error::OpError;
use crate::ops::JsonOp;
use crate::ops::MinimalOp;
use crate::permissions::DenoPermissions;
@ -128,15 +128,15 @@ impl State {
pub fn stateful_op<D>(
&self,
dispatcher: D,
) -> impl Fn(Value, Option<ZeroCopyBuf>) -> Result<JsonOp, ErrBox>
) -> impl Fn(Value, Option<ZeroCopyBuf>) -> Result<JsonOp, OpError>
where
D: Fn(&State, Value, Option<ZeroCopyBuf>) -> Result<JsonOp, ErrBox>,
D: Fn(&State, Value, Option<ZeroCopyBuf>) -> Result<JsonOp, OpError>,
{
let state = self.clone();
move |args: Value,
zero_copy: Option<ZeroCopyBuf>|
-> Result<JsonOp, ErrBox> { dispatcher(&state, args, zero_copy) }
-> Result<JsonOp, OpError> { dispatcher(&state, args, zero_copy) }
}
}
@ -171,7 +171,7 @@ impl Loader for State {
let module_specifier = module_specifier.clone();
if is_dyn_import {
if let Err(e) = self.check_dyn_import(&module_specifier) {
return async move { Err(e) }.boxed_local();
return async move { Err(e.into()) }.boxed_local();
}
}
@ -278,44 +278,44 @@ impl State {
}
#[inline]
pub fn check_read(&self, path: &Path) -> Result<(), ErrBox> {
pub fn check_read(&self, path: &Path) -> Result<(), OpError> {
self.borrow().permissions.check_read(path)
}
#[inline]
pub fn check_write(&self, path: &Path) -> Result<(), ErrBox> {
pub fn check_write(&self, path: &Path) -> Result<(), OpError> {
self.borrow().permissions.check_write(path)
}
#[inline]
pub fn check_env(&self) -> Result<(), ErrBox> {
pub fn check_env(&self) -> Result<(), OpError> {
self.borrow().permissions.check_env()
}
#[inline]
pub fn check_net(&self, hostname: &str, port: u16) -> Result<(), ErrBox> {
pub fn check_net(&self, hostname: &str, port: u16) -> Result<(), OpError> {
self.borrow().permissions.check_net(hostname, port)
}
#[inline]
pub fn check_net_url(&self, url: &url::Url) -> Result<(), ErrBox> {
pub fn check_net_url(&self, url: &url::Url) -> Result<(), OpError> {
self.borrow().permissions.check_net_url(url)
}
#[inline]
pub fn check_run(&self) -> Result<(), ErrBox> {
pub fn check_run(&self) -> Result<(), OpError> {
self.borrow().permissions.check_run()
}
#[inline]
pub fn check_plugin(&self, filename: &Path) -> Result<(), ErrBox> {
pub fn check_plugin(&self, filename: &Path) -> Result<(), OpError> {
self.borrow().permissions.check_plugin(filename)
}
pub fn check_dyn_import(
&self,
module_specifier: &ModuleSpecifier,
) -> Result<(), ErrBox> {
) -> Result<(), OpError> {
let u = module_specifier.as_url();
match u.scheme() {
"http" | "https" => {
@ -332,7 +332,7 @@ impl State {
self.check_read(Path::new(&path))?;
Ok(())
}
_ => Err(permission_denied()),
_ => unreachable!(),
}
}