summaryrefslogtreecommitdiff
path: root/cli/deno_error.rs
diff options
context:
space:
mode:
authorBartek Iwańczuk <biwanczuk@gmail.com>2020-02-21 10:36:13 -0500
committerGitHub <noreply@github.com>2020-02-21 10:36:13 -0500
commitdd8a10948195f231a6a9eb652e3f208813904ad6 (patch)
treef9a4afeb67bbead882c29c2458a5f1f99e2e42db /cli/deno_error.rs
parentd9efb8c02a0036d755c35e8e9c88d58bd45a9e2b (diff)
refactor: remove unneeded ErrorKinds (#3936)
Diffstat (limited to 'cli/deno_error.rs')
-rw-r--r--cli/deno_error.rs208
1 files changed, 73 insertions, 135 deletions
diff --git a/cli/deno_error.rs b/cli/deno_error.rs
index 0e1a8d9cf..97c7c8a7c 100644
--- a/cli/deno_error.rs
+++ b/cli/deno_error.rs
@@ -1,8 +1,34 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::diagnostics::Diagnostic;
-use crate::fmt_errors::JSError;
+
+//! 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;
-pub use crate::msg::ErrorKind;
use deno_core::AnyError;
use deno_core::ErrBox;
use deno_core::ModuleResolutionError;
@@ -16,6 +42,34 @@ 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,
@@ -76,11 +130,11 @@ pub fn permission_denied_msg(msg: String) -> ErrBox {
}
pub fn no_buffer_specified() -> ErrBox {
- StaticError(ErrorKind::InvalidInput, "no buffer specified").into()
+ StaticError(ErrorKind::TypeError, "no buffer specified").into()
}
pub fn invalid_address_syntax() -> ErrBox {
- StaticError(ErrorKind::InvalidInput, "invalid address syntax").into()
+ StaticError(ErrorKind::TypeError, "invalid address syntax").into()
}
pub fn other_error(msg: String) -> ErrBox {
@@ -103,18 +157,6 @@ impl GetErrorKind for StaticError {
}
}
-impl GetErrorKind for JSError {
- fn kind(&self) -> ErrorKind {
- ErrorKind::JSError
- }
-}
-
-impl GetErrorKind for Diagnostic {
- fn kind(&self) -> ErrorKind {
- ErrorKind::Diagnostic
- }
-}
-
impl GetErrorKind for ImportMapError {
fn kind(&self) -> ErrorKind {
ErrorKind::Other
@@ -123,12 +165,7 @@ impl GetErrorKind for ImportMapError {
impl GetErrorKind for ModuleResolutionError {
fn kind(&self) -> ErrorKind {
- use ModuleResolutionError::*;
- match self {
- InvalidUrl(ref err) | InvalidBaseUrl(ref err) => err.kind(),
- InvalidPath(_) => ErrorKind::InvalidPath,
- ImportPrefixMissing(_, _) => ErrorKind::ImportPrefixMissing,
- }
+ ErrorKind::URIError
}
}
@@ -156,13 +193,13 @@ impl GetErrorKind for io::Error {
AddrNotAvailable => ErrorKind::AddrNotAvailable,
BrokenPipe => ErrorKind::BrokenPipe,
AlreadyExists => ErrorKind::AlreadyExists,
- WouldBlock => ErrorKind::WouldBlock,
- InvalidInput => ErrorKind::InvalidInput,
+ InvalidInput => ErrorKind::TypeError,
InvalidData => ErrorKind::InvalidData,
TimedOut => ErrorKind::TimedOut,
Interrupted => ErrorKind::Interrupted,
WriteZero => ErrorKind::WriteZero,
UnexpectedEof => ErrorKind::UnexpectedEof,
+ WouldBlock => unreachable!(),
_ => ErrorKind::Other,
}
}
@@ -170,7 +207,7 @@ impl GetErrorKind for io::Error {
impl GetErrorKind for url::ParseError {
fn kind(&self) -> ErrorKind {
- ErrorKind::UrlParse
+ ErrorKind::URIError
}
}
@@ -211,8 +248,8 @@ impl GetErrorKind for serde_json::error::Error {
fn kind(&self) -> ErrorKind {
use serde_json::error::*;
match self.classify() {
- Category::Io => ErrorKind::InvalidInput,
- Category::Syntax => ErrorKind::InvalidInput,
+ Category::Io => ErrorKind::TypeError,
+ Category::Syntax => ErrorKind::TypeError,
Category::Data => ErrorKind::InvalidData,
Category::Eof => ErrorKind::UnexpectedEof,
}
@@ -230,10 +267,13 @@ mod unix {
fn kind(&self) -> ErrorKind {
match self {
Sys(EPERM) => ErrorKind::PermissionDenied,
- Sys(EINVAL) => ErrorKind::InvalidInput,
+ Sys(EINVAL) => ErrorKind::TypeError,
Sys(ENOENT) => ErrorKind::NotFound,
- Sys(_) => ErrorKind::UnixError,
- _ => ErrorKind::Other,
+ Sys(UnknownErrno) => unreachable!(),
+ Sys(_) => unreachable!(),
+ Error::InvalidPath => ErrorKind::TypeError,
+ Error::InvalidUtf8 => ErrorKind::InvalidData,
+ Error::UnsupportedOperation => unreachable!(),
}
}
}
@@ -268,11 +308,9 @@ impl GetErrorKind for dyn AnyError {
None
.or_else(|| self.downcast_ref::<DenoError>().map(Get::kind))
- .or_else(|| self.downcast_ref::<Diagnostic>().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::<JSError>().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))
@@ -294,93 +332,7 @@ impl GetErrorKind for dyn AnyError {
#[cfg(test)]
mod tests {
use super::*;
- use crate::colors::strip_ansi_codes;
- use crate::diagnostics::Diagnostic;
- use crate::diagnostics::DiagnosticCategory;
- use crate::diagnostics::DiagnosticItem;
use deno_core::ErrBox;
- use deno_core::StackFrame;
- use deno_core::V8Exception;
-
- fn js_error() -> JSError {
- JSError::new(V8Exception {
- message: "Error: foo bar".to_string(),
- source_line: None,
- script_resource_name: None,
- line_number: None,
- start_position: None,
- end_position: None,
- error_level: None,
- start_column: None,
- end_column: None,
- frames: vec![
- StackFrame {
- line: 4,
- column: 16,
- script_name: "foo_bar.ts".to_string(),
- function_name: "foo".to_string(),
- is_eval: false,
- is_constructor: false,
- is_wasm: false,
- },
- StackFrame {
- line: 5,
- column: 20,
- script_name: "bar_baz.ts".to_string(),
- function_name: "qat".to_string(),
- is_eval: false,
- is_constructor: false,
- is_wasm: false,
- },
- StackFrame {
- line: 1,
- column: 1,
- script_name: "deno_main.js".to_string(),
- function_name: "".to_string(),
- is_eval: false,
- is_constructor: false,
- is_wasm: false,
- },
- ],
- })
- }
-
- fn diagnostic() -> Diagnostic {
- Diagnostic {
- items: vec![
- DiagnosticItem {
- message: "Example 1".to_string(),
- message_chain: None,
- code: 2322,
- category: DiagnosticCategory::Error,
- start_position: Some(267),
- end_position: Some(273),
- source_line: Some(" values: o => [".to_string()),
- line_number: Some(18),
- script_resource_name: Some(
- "deno/tests/complex_diagnostics.ts".to_string(),
- ),
- start_column: Some(2),
- end_column: Some(8),
- related_information: None,
- },
- DiagnosticItem {
- message: "Example 2".to_string(),
- message_chain: None,
- code: 2000,
- category: DiagnosticCategory::Error,
- start_position: Some(2),
- end_position: Some(2),
- source_line: Some(" values: undefined,".to_string()),
- line_number: Some(128),
- script_resource_name: Some("/foo/bar.ts".to_string()),
- start_column: Some(2),
- end_column: Some(8),
- related_information: None,
- },
- ],
- }
- }
fn io_error() -> io::Error {
io::Error::from(io::ErrorKind::NotFound)
@@ -414,27 +366,13 @@ mod tests {
#[test]
fn test_url_error() {
let err = ErrBox::from(url_error());
- assert_eq!(err.kind(), ErrorKind::UrlParse);
+ 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_diagnostic() {
- let err = ErrBox::from(diagnostic());
- assert_eq!(err.kind(), ErrorKind::Diagnostic);
- assert_eq!(strip_ansi_codes(&err.to_string()), "error TS2322: Example 1\n\n► deno/tests/complex_diagnostics.ts:19:3\n\n19 values: o => [\n ~~~~~~\n\nerror TS2000: Example 2\n\n► /foo/bar.ts:129:3\n\n129 values: undefined,\n ~~~~~~\n\n\nFound 2 errors.\n");
- }
-
- #[test]
- fn test_js_error() {
- let err = ErrBox::from(js_error());
- assert_eq!(err.kind(), ErrorKind::JSError);
- assert_eq!(strip_ansi_codes(&err.to_string()), "error: Error: foo bar\n at foo (foo_bar.ts:5:17)\n at qat (bar_baz.ts:6:21)\n at deno_main.js:2:2");
- }
-
- #[test]
fn test_import_map_error() {
let err = ErrBox::from(import_map_error());
assert_eq!(err.kind(), ErrorKind::Other);
@@ -466,7 +404,7 @@ mod tests {
#[test]
fn test_no_buffer_specified() {
let err = no_buffer_specified();
- assert_eq!(err.kind(), ErrorKind::InvalidInput);
+ assert_eq!(err.kind(), ErrorKind::TypeError);
assert_eq!(err.to_string(), "no buffer specified");
}
}