summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/op_error.rs153
-rw-r--r--cli/ops/dispatch_json.rs2
-rw-r--r--cli/ops/dispatch_minimal.rs27
-rw-r--r--cli/ops/idna.rs14
-rw-r--r--cli/permissions.rs11
-rw-r--r--cli/rt/01_errors.js96
-rw-r--r--cli/rt/10_dispatch_json.js3
-rw-r--r--cli/rt/10_dispatch_minimal.js13
-rw-r--r--cli/rt/99_main.js29
-rw-r--r--cli/tests/unit/dispatch_minimal_test.ts4
-rw-r--r--cli/tsc/01_errors.js96
-rw-r--r--cli/tsc/10_dispatch_json.js4
-rw-r--r--cli/tsc/99_main_compiler.js22
-rw-r--r--core/core.js16
14 files changed, 197 insertions, 293 deletions
diff --git a/cli/op_error.rs b/cli/op_error.rs
index 3cbe27a06..263363122 100644
--- a/cli/op_error.rs
+++ b/cli/op_error.rs
@@ -54,15 +54,75 @@ pub enum ErrorKind {
Busy = 23,
}
+impl From<ErrorKind> for String {
+ fn from(kind: ErrorKind) -> Self {
+ let s = match kind {
+ ErrorKind::NotFound => "NotFound",
+ ErrorKind::PermissionDenied => "PermissionDenied",
+ ErrorKind::ConnectionRefused => "ConnectionRefused",
+ ErrorKind::ConnectionReset => "ConnectionReset",
+ ErrorKind::ConnectionAborted => "ConnectionAborted",
+ ErrorKind::NotConnected => "NotConnected",
+ ErrorKind::AddrInUse => "AddrInUse",
+ ErrorKind::AddrNotAvailable => "AddrNotAvailable",
+ ErrorKind::BrokenPipe => "BrokenPipe",
+ ErrorKind::AlreadyExists => "AlreadyExists",
+ ErrorKind::InvalidData => "InvalidData",
+ ErrorKind::TimedOut => "TimedOut",
+ ErrorKind::Interrupted => "Interrupted",
+ ErrorKind::WriteZero => "WriteZero",
+ ErrorKind::UnexpectedEof => "UnexpectedEof",
+ ErrorKind::BadResource => "BadResource",
+ ErrorKind::Http => "Http",
+ ErrorKind::URIError => "URIError",
+ ErrorKind::TypeError => "TypeError",
+ ErrorKind::Other => "Other",
+ ErrorKind::Busy => "Busy",
+ };
+
+ s.to_string()
+ }
+}
+
+fn error_str_to_kind(kind_str: &str) -> ErrorKind {
+ match kind_str {
+ "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,
+ "InvalidData" => ErrorKind::InvalidData,
+ "TimedOut" => ErrorKind::TimedOut,
+ "Interrupted" => ErrorKind::Interrupted,
+ "WriteZero" => ErrorKind::WriteZero,
+ "UnexpectedEof" => ErrorKind::UnexpectedEof,
+ "BadResource" => ErrorKind::BadResource,
+ "Http" => ErrorKind::Http,
+ "URIError" => ErrorKind::URIError,
+ "TypeError" => ErrorKind::TypeError,
+ "Other" => ErrorKind::Other,
+ "Busy" => ErrorKind::Busy,
+ _ => panic!("unknown error kind"),
+ }
+}
+
#[derive(Debug)]
pub struct OpError {
- pub kind: ErrorKind,
+ pub kind_str: String,
pub msg: String,
}
impl OpError {
fn new(kind: ErrorKind, msg: String) -> Self {
- Self { kind, msg }
+ Self {
+ kind_str: kind.into(),
+ msg,
+ }
}
pub fn not_found(msg: String) -> Self {
@@ -112,6 +172,10 @@ impl OpError {
"resource is unavailable because it is in use by a promise".to_string(),
)
}
+
+ pub fn invalid_domain_error() -> OpError {
+ OpError::new(ErrorKind::TypeError, "Invalid domain.".to_string())
+ }
}
impl Error for OpError {}
@@ -130,10 +194,7 @@ impl From<ImportMapError> for OpError {
impl From<&ImportMapError> for OpError {
fn from(error: &ImportMapError) -> Self {
- Self {
- kind: ErrorKind::Other,
- msg: error.to_string(),
- }
+ Self::new(ErrorKind::Other, error.to_string())
}
}
@@ -145,10 +206,7 @@ impl From<ModuleResolutionError> for OpError {
impl From<&ModuleResolutionError> for OpError {
fn from(error: &ModuleResolutionError) -> Self {
- Self {
- kind: ErrorKind::URIError,
- msg: error.to_string(),
- }
+ Self::new(ErrorKind::URIError, error.to_string())
}
}
@@ -166,10 +224,7 @@ impl From<&VarError> for OpError {
NotUnicode(..) => ErrorKind::InvalidData,
};
- Self {
- kind,
- msg: error.to_string(),
- }
+ Self::new(kind, error.to_string())
}
}
@@ -206,10 +261,7 @@ impl From<&io::Error> for OpError {
_ => unreachable!(),
};
- Self {
- kind,
- msg: error.to_string(),
- }
+ Self::new(kind, error.to_string())
}
}
@@ -221,10 +273,7 @@ impl From<url::ParseError> for OpError {
impl From<&url::ParseError> for OpError {
fn from(error: &url::ParseError) -> Self {
- Self {
- kind: ErrorKind::URIError,
- msg: error.to_string(),
- }
+ Self::new(ErrorKind::URIError, error.to_string())
}
}
impl From<reqwest::Error> for OpError {
@@ -252,14 +301,8 @@ impl From<&reqwest::Error> for OpError {
.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(),
- },
+ .unwrap_or_else(|| Self::new(ErrorKind::Http, error.to_string())),
+ None => Self::new(ErrorKind::Http, error.to_string()),
}
}
}
@@ -282,10 +325,7 @@ impl From<&ReadlineError> for OpError {
_ => unimplemented!(),
};
- Self {
- kind,
- msg: error.to_string(),
- }
+ Self::new(kind, error.to_string())
}
}
@@ -305,10 +345,7 @@ impl From<&serde_json::error::Error> for OpError {
Category::Eof => ErrorKind::UnexpectedEof,
};
- Self {
- kind,
- msg: error.to_string(),
- }
+ Self::new(kind, error.to_string())
}
}
@@ -328,10 +365,7 @@ impl From<nix::Error> for OpError {
nix::Error::UnsupportedOperation => unreachable!(),
};
- Self {
- kind,
- msg: error.to_string(),
- }
+ Self::new(kind, error.to_string())
}
}
@@ -352,10 +386,7 @@ impl From<&dlopen::Error> for OpError {
NullSymbol => ErrorKind::Other,
};
- Self {
- kind,
- msg: error.to_string(),
- }
+ Self::new(kind, error.to_string())
}
}
@@ -376,10 +407,7 @@ impl From<&notify::Error> for OpError {
InvalidConfig(_) => ErrorKind::InvalidData,
};
- Self {
- kind,
- msg: error.to_string(),
- }
+ Self::new(kind, error.to_string())
}
}
@@ -391,10 +419,7 @@ impl From<SwcDiagnosticBuffer> for OpError {
impl From<&SwcDiagnosticBuffer> for OpError {
fn from(error: &SwcDiagnosticBuffer) -> Self {
- Self {
- kind: ErrorKind::Other,
- msg: error.diagnostics.join(", "),
- }
+ Self::new(ErrorKind::Other, error.diagnostics.join(", "))
}
}
@@ -412,9 +437,9 @@ impl From<ErrBox> for OpError {
None
.or_else(|| {
- error
- .downcast_ref::<OpError>()
- .map(|e| OpError::new(e.kind, e.msg.to_string()))
+ error.downcast_ref::<OpError>().map(|e| {
+ OpError::new(error_str_to_kind(&e.kind_str), 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()))
@@ -467,21 +492,21 @@ mod tests {
#[test]
fn test_simple_error() {
let err = OpError::not_found("foo".to_string());
- assert_eq!(err.kind, ErrorKind::NotFound);
+ assert_eq!(err.kind_str, "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.kind_str, "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.kind_str, "URIError");
assert_eq!(err.to_string(), "empty host");
}
@@ -490,21 +515,21 @@ mod tests {
#[test]
fn test_import_map_error() {
let err = OpError::from(import_map_error());
- assert_eq!(err.kind, ErrorKind::Other);
+ assert_eq!(err.kind_str, "Other");
assert_eq!(err.to_string(), "an import map error");
}
#[test]
fn test_bad_resource() {
let err = OpError::bad_resource("Resource has been closed".to_string());
- assert_eq!(err.kind, ErrorKind::BadResource);
+ assert_eq!(err.kind_str, "BadResource");
assert_eq!(err.to_string(), "Resource has been closed");
}
#[test]
fn test_bad_resource_id() {
let err = OpError::bad_resource_id();
- assert_eq!(err.kind, ErrorKind::BadResource);
+ assert_eq!(err.kind_str, "BadResource");
assert_eq!(err.to_string(), "Bad resource ID");
}
@@ -513,7 +538,7 @@ mod tests {
let err = OpError::permission_denied(
"run again with the --allow-net flag".to_string(),
);
- assert_eq!(err.kind, ErrorKind::PermissionDenied);
+ assert_eq!(err.kind_str, "PermissionDenied");
assert_eq!(err.to_string(), "run again with the --allow-net flag");
}
}
diff --git a/cli/ops/dispatch_json.rs b/cli/ops/dispatch_json.rs
index c3a1c3b3f..ad6947dd1 100644
--- a/cli/ops/dispatch_json.rs
+++ b/cli/ops/dispatch_json.rs
@@ -27,7 +27,7 @@ pub enum JsonOp {
fn json_err(err: OpError) -> Value {
json!({
"message": err.msg,
- "kind": err.kind as u32,
+ "kind": err.kind_str,
})
}
diff --git a/cli/ops/dispatch_minimal.rs b/cli/ops/dispatch_minimal.rs
index c37e57e45..9cb81d4bc 100644
--- a/cli/ops/dispatch_minimal.rs
+++ b/cli/ops/dispatch_minimal.rs
@@ -40,21 +40,24 @@ impl Into<Buf> for Record {
pub struct ErrorRecord {
pub promise_id: i32,
pub arg: i32,
- pub error_code: i32,
+ pub error_len: i32,
+ pub error_code: Vec<u8>,
pub error_message: Vec<u8>,
}
impl Into<Buf> for ErrorRecord {
fn into(self) -> Buf {
- let v32: Vec<i32> = vec![self.promise_id, self.arg, self.error_code];
+ let v32: Vec<i32> = vec![self.promise_id, self.arg, self.error_len];
let mut v8: Vec<u8> = Vec::new();
for n in v32 {
v8.write_i32::<LittleEndian>(n).unwrap();
}
+ let mut code = self.error_code;
let mut message = self.error_message;
- // Align to 32bit word, padding with the space character.
- message.resize((message.len() + 3usize) & !3usize, b' ');
+ v8.append(&mut code);
v8.append(&mut message);
+ // Align to 32bit word, padding with the space character.
+ v8.resize((v8.len() + 3usize) & !3usize, b' ');
v8.into_boxed_slice()
}
}
@@ -62,13 +65,14 @@ impl Into<Buf> for ErrorRecord {
#[test]
fn test_error_record() {
let expected = vec![
- 1, 0, 0, 0, 255, 255, 255, 255, 10, 0, 0, 0, 69, 114, 114, 111, 114, 32,
- 32, 32,
+ 1, 0, 0, 0, 255, 255, 255, 255, 11, 0, 0, 0, 66, 97, 100, 82, 101, 115,
+ 111, 117, 114, 99, 101, 69, 114, 114, 111, 114,
];
let err_record = ErrorRecord {
promise_id: 1,
arg: -1,
- error_code: 10,
+ error_len: 11,
+ error_code: "BadResource".to_string().as_bytes().to_owned(),
error_message: "Error".to_string().as_bytes().to_owned(),
};
let buf: Buf = err_record.into();
@@ -128,7 +132,8 @@ where
let error_record = ErrorRecord {
promise_id: 0,
arg: -1,
- error_code: e.kind as i32,
+ error_len: e.kind_str.len() as i32,
+ error_code: e.kind_str.as_bytes().to_owned(),
error_message: e.msg.as_bytes().to_owned(),
};
return Op::Sync(error_record.into());
@@ -148,7 +153,8 @@ where
let error_record = ErrorRecord {
promise_id: record.promise_id,
arg: -1,
- error_code: err.kind as i32,
+ error_len: err.kind_str.len() as i32,
+ error_code: err.kind_str.as_bytes().to_owned(),
error_message: err.msg.as_bytes().to_owned(),
};
error_record.into()
@@ -165,7 +171,8 @@ where
let error_record = ErrorRecord {
promise_id: record.promise_id,
arg: -1,
- error_code: err.kind as i32,
+ error_len: err.kind_str.len() as i32,
+ error_code: err.kind_str.as_bytes().to_owned(),
error_message: err.msg.as_bytes().to_owned(),
};
error_record.into()
diff --git a/cli/ops/idna.rs b/cli/ops/idna.rs
index 8ecef4862..ee78307dc 100644
--- a/cli/ops/idna.rs
+++ b/cli/ops/idna.rs
@@ -3,7 +3,7 @@
//! https://url.spec.whatwg.org/#idna
use super::dispatch_json::{Deserialize, JsonOp, Value};
-use crate::op_error::{ErrorKind, OpError};
+use crate::op_error::OpError;
use crate::state::State;
use deno_core::CoreIsolate;
use deno_core::ZeroCopyBuf;
@@ -13,13 +13,6 @@ pub fn init(i: &mut CoreIsolate, s: &State) {
i.register_op("op_domain_to_ascii", s.stateful_json_op(op_domain_to_ascii));
}
-fn invalid_domain_error() -> OpError {
- OpError {
- kind: ErrorKind::TypeError,
- msg: "Invalid domain.".to_string(),
- }
-}
-
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct DomainToAscii {
@@ -35,9 +28,10 @@ fn op_domain_to_ascii(
let args: DomainToAscii = serde_json::from_value(args)?;
let domain = if args.be_strict {
domain_to_ascii_strict(args.domain.as_str())
- .map_err(|_| invalid_domain_error())?
+ .map_err(|_| OpError::invalid_domain_error())?
} else {
- domain_to_ascii(args.domain.as_str()).map_err(|_| invalid_domain_error())?
+ domain_to_ascii(args.domain.as_str())
+ .map_err(|_| OpError::invalid_domain_error())?
};
Ok(JsonOp::Sync(json!(domain)))
}
diff --git a/cli/permissions.rs b/cli/permissions.rs
index 2e378b497..c89f8bcdb 100644
--- a/cli/permissions.rs
+++ b/cli/permissions.rs
@@ -860,8 +860,8 @@ mod tests {
perms4
.request_net(&Some("localhost:8080"))
.unwrap_err()
- .kind,
- crate::op_error::ErrorKind::URIError
+ .kind_str,
+ "URIError"
);
let mut perms5 = Permissions::from_flags(&Flags {
@@ -870,8 +870,11 @@ mod tests {
});
set_prompt_result(false);
assert_eq!(
- perms5.request_net(&Some("file:/1.txt")).unwrap_err().kind,
- crate::op_error::ErrorKind::URIError
+ perms5
+ .request_net(&Some("file:/1.txt"))
+ .unwrap_err()
+ .kind_str,
+ "URIError"
);
drop(guard);
diff --git a/cli/rt/01_errors.js b/cli/rt/01_errors.js
index 8390dd803..fb2bb78c2 100644
--- a/cli/rt/01_errors.js
+++ b/cli/rt/01_errors.js
@@ -1,101 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
((window) => {
- // Warning! The values in this enum are duplicated in cli/op_error.rs
- // Update carefully!
- const ErrorKind = {
- 1: "NotFound",
- 2: "PermissionDenied",
- 3: "ConnectionRefused",
- 4: "ConnectionReset",
- 5: "ConnectionAborted",
- 6: "NotConnected",
- 7: "AddrInUse",
- 8: "AddrNotAvailable",
- 9: "BrokenPipe",
- 10: "AlreadyExists",
- 13: "InvalidData",
- 14: "TimedOut",
- 15: "Interrupted",
- 16: "WriteZero",
- 17: "UnexpectedEof",
- 18: "BadResource",
- 19: "Http",
- 20: "URIError",
- 21: "TypeError",
- 22: "Other",
- 23: "Busy",
-
- 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,
- Busy: 23,
- };
-
- function getErrorClass(kind) {
- switch (kind) {
- case ErrorKind.TypeError:
- return TypeError;
- case ErrorKind.Other:
- return Error;
- case ErrorKind.URIError:
- return URIError;
- case ErrorKind.NotFound:
- return NotFound;
- case ErrorKind.PermissionDenied:
- return PermissionDenied;
- case ErrorKind.ConnectionRefused:
- return ConnectionRefused;
- case ErrorKind.ConnectionReset:
- return ConnectionReset;
- case ErrorKind.ConnectionAborted:
- return ConnectionAborted;
- case ErrorKind.NotConnected:
- return NotConnected;
- case ErrorKind.AddrInUse:
- return AddrInUse;
- case ErrorKind.AddrNotAvailable:
- return AddrNotAvailable;
- case ErrorKind.BrokenPipe:
- return BrokenPipe;
- case ErrorKind.AlreadyExists:
- return AlreadyExists;
- case ErrorKind.InvalidData:
- return InvalidData;
- case ErrorKind.TimedOut:
- return TimedOut;
- case ErrorKind.Interrupted:
- return Interrupted;
- case ErrorKind.WriteZero:
- return WriteZero;
- case ErrorKind.UnexpectedEof:
- return UnexpectedEof;
- case ErrorKind.BadResource:
- return BadResource;
- case ErrorKind.Http:
- return Http;
- case ErrorKind.Busy:
- return Busy;
- }
- }
-
class NotFound extends Error {
constructor(msg) {
super(msg);
@@ -245,6 +150,5 @@
window.__bootstrap.errors = {
errors,
- getErrorClass,
};
})(this);
diff --git a/cli/rt/10_dispatch_json.js b/cli/rt/10_dispatch_json.js
index 3d19ea62a..05b4d46ed 100644
--- a/cli/rt/10_dispatch_json.js
+++ b/cli/rt/10_dispatch_json.js
@@ -3,7 +3,6 @@
((window) => {
const core = window.Deno.core;
const util = window.__bootstrap.util;
- const getErrorClass = window.__bootstrap.errors.getErrorClass;
// Using an object without a prototype because `Map` was causing GC problems.
const promiseTable = Object.create(null);
let _nextPromiseId = 1;
@@ -22,7 +21,7 @@
function unwrapResponse(res) {
if (res.err != null) {
- throw new (getErrorClass(res.err.kind))(res.err.message);
+ throw new (core.getErrorClass(res.err.kind))(res.err.message);
}
util.assert(res.ok != null);
return res.ok;
diff --git a/cli/rt/10_dispatch_minimal.js b/cli/rt/10_dispatch_minimal.js
index 6137449f4..0a0a4f99f 100644
--- a/cli/rt/10_dispatch_minimal.js
+++ b/cli/rt/10_dispatch_minimal.js
@@ -3,7 +3,6 @@
((window) => {
const core = window.Deno.core;
const util = window.__bootstrap.util;
- const errorNs = window.__bootstrap.errors;
// Using an object without a prototype because `Map` was causing GC problems.
const promiseTableMin = Object.create(null);
@@ -32,11 +31,13 @@
let err;
if (arg < 0) {
- const kind = result;
- const message = decoder.decode(ui8.subarray(12));
- err = { kind, message };
+ const codeLen = result;
+ const codeAndMessage = decoder.decode(ui8.subarray(12));
+ const errorCode = codeAndMessage.slice(0, codeLen);
+ const message = codeAndMessage.slice(codeLen);
+ err = { kind: errorCode, message };
} else if (ui8.length != 12) {
- throw new errorNs.errors.InvalidData("BadMessage");
+ throw new TypeError("Malformed response message");
}
return {
@@ -49,7 +50,7 @@
function unwrapResponse(res) {
if (res.err != null) {
- throw new (errorNs.getErrorClass(res.err.kind))(res.err.message);
+ throw new (core.getErrorClass(res.err.kind))(res.err.message);
}
return res.result;
}
diff --git a/cli/rt/99_main.js b/cli/rt/99_main.js
index 325881b5a..873e42291 100644
--- a/cli/rt/99_main.js
+++ b/cli/rt/99_main.js
@@ -34,6 +34,7 @@ delete Object.prototype.__proto__;
const fetch = window.__bootstrap.fetch;
const denoNs = window.__bootstrap.denoNs;
const denoNsUnstable = window.__bootstrap.denoNsUnstable;
+ const errors = window.__bootstrap.errors.errors;
let windowIsClosing = false;
@@ -175,6 +176,30 @@ delete Object.prototype.__proto__;
return s;
}
+ function registerErrors() {
+ core.registerErrorClass("NotFound", errors.NotFound);
+ core.registerErrorClass("PermissionDenied", errors.PermissionDenied);
+ core.registerErrorClass("ConnectionRefused", errors.ConnectionRefused);
+ core.registerErrorClass("ConnectionReset", errors.ConnectionReset);
+ core.registerErrorClass("ConnectionAborted", errors.ConnectionAborted);
+ core.registerErrorClass("NotConnected", errors.NotConnected);
+ core.registerErrorClass("AddrInUse", errors.AddrInUse);
+ core.registerErrorClass("AddrNotAvailable", errors.AddrNotAvailable);
+ core.registerErrorClass("BrokenPipe", errors.BrokenPipe);
+ core.registerErrorClass("AlreadyExists", errors.AlreadyExists);
+ core.registerErrorClass("InvalidData", errors.InvalidData);
+ core.registerErrorClass("TimedOut", errors.TimedOut);
+ core.registerErrorClass("Interrupted", errors.Interrupted);
+ core.registerErrorClass("WriteZero", errors.WriteZero);
+ core.registerErrorClass("UnexpectedEof", errors.UnexpectedEof);
+ core.registerErrorClass("BadResource", errors.BadResource);
+ core.registerErrorClass("Http", errors.Http);
+ core.registerErrorClass("URIError", URIError);
+ core.registerErrorClass("TypeError", TypeError);
+ core.registerErrorClass("Other", Error);
+ core.registerErrorClass("Busy", errors.Busy);
+ }
+
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope
const windowOrWorkerGlobalScopeMethods = {
atob: util.writable(atob),
@@ -290,6 +315,8 @@ delete Object.prototype.__proto__;
const { args, cwd, noColor, pid, ppid, repl, unstableFlag } =
runtimeStart();
+ registerErrors();
+
const finalDenoNs = {
core,
internal: internalSymbol,
@@ -347,6 +374,8 @@ delete Object.prototype.__proto__;
internalName ?? name,
);
+ registerErrors();
+
const finalDenoNs = {
core,
internal: internalSymbol,
diff --git a/cli/tests/unit/dispatch_minimal_test.ts b/cli/tests/unit/dispatch_minimal_test.ts
index 26296b469..e10acfc54 100644
--- a/cli/tests/unit/dispatch_minimal_test.ts
+++ b/cli/tests/unit/dispatch_minimal_test.ts
@@ -43,7 +43,7 @@ unitTest(function malformedMinimalControlBuffer(): void {
header.byteLength / 4,
);
const arg = buf32[1];
- const message = new TextDecoder().decode(res.slice(12)).trim();
+ const codeAndMessage = new TextDecoder().decode(res.slice(12)).trim();
assert(arg < 0);
- assertEquals(message, "Unparsable control buffer");
+ assertEquals(codeAndMessage, "TypeErrorUnparsable control buffer");
});
diff --git a/cli/tsc/01_errors.js b/cli/tsc/01_errors.js
index 8390dd803..fb2bb78c2 100644
--- a/cli/tsc/01_errors.js
+++ b/cli/tsc/01_errors.js
@@ -1,101 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
((window) => {
- // Warning! The values in this enum are duplicated in cli/op_error.rs
- // Update carefully!
- const ErrorKind = {
- 1: "NotFound",
- 2: "PermissionDenied",
- 3: "ConnectionRefused",
- 4: "ConnectionReset",
- 5: "ConnectionAborted",
- 6: "NotConnected",
- 7: "AddrInUse",
- 8: "AddrNotAvailable",
- 9: "BrokenPipe",
- 10: "AlreadyExists",
- 13: "InvalidData",
- 14: "TimedOut",
- 15: "Interrupted",
- 16: "WriteZero",
- 17: "UnexpectedEof",
- 18: "BadResource",
- 19: "Http",
- 20: "URIError",
- 21: "TypeError",
- 22: "Other",
- 23: "Busy",
-
- 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,
- Busy: 23,
- };
-
- function getErrorClass(kind) {
- switch (kind) {
- case ErrorKind.TypeError:
- return TypeError;
- case ErrorKind.Other:
- return Error;
- case ErrorKind.URIError:
- return URIError;
- case ErrorKind.NotFound:
- return NotFound;
- case ErrorKind.PermissionDenied:
- return PermissionDenied;
- case ErrorKind.ConnectionRefused:
- return ConnectionRefused;
- case ErrorKind.ConnectionReset:
- return ConnectionReset;
- case ErrorKind.ConnectionAborted:
- return ConnectionAborted;
- case ErrorKind.NotConnected:
- return NotConnected;
- case ErrorKind.AddrInUse:
- return AddrInUse;
- case ErrorKind.AddrNotAvailable:
- return AddrNotAvailable;
- case ErrorKind.BrokenPipe:
- return BrokenPipe;
- case ErrorKind.AlreadyExists:
- return AlreadyExists;
- case ErrorKind.InvalidData:
- return InvalidData;
- case ErrorKind.TimedOut:
- return TimedOut;
- case ErrorKind.Interrupted:
- return Interrupted;
- case ErrorKind.WriteZero:
- return WriteZero;
- case ErrorKind.UnexpectedEof:
- return UnexpectedEof;
- case ErrorKind.BadResource:
- return BadResource;
- case ErrorKind.Http:
- return Http;
- case ErrorKind.Busy:
- return Busy;
- }
- }
-
class NotFound extends Error {
constructor(msg) {
super(msg);
@@ -245,6 +150,5 @@
window.__bootstrap.errors = {
errors,
- getErrorClass,
};
})(this);
diff --git a/cli/tsc/10_dispatch_json.js b/cli/tsc/10_dispatch_json.js
index 3d19ea62a..a25014789 100644
--- a/cli/tsc/10_dispatch_json.js
+++ b/cli/tsc/10_dispatch_json.js
@@ -3,7 +3,7 @@
((window) => {
const core = window.Deno.core;
const util = window.__bootstrap.util;
- const getErrorClass = window.__bootstrap.errors.getErrorClass;
+
// Using an object without a prototype because `Map` was causing GC problems.
const promiseTable = Object.create(null);
let _nextPromiseId = 1;
@@ -22,7 +22,7 @@
function unwrapResponse(res) {
if (res.err != null) {
- throw new (getErrorClass(res.err.kind))(res.err.message);
+ throw new (core.getErrorClass(res.err.kind))(res.err.message);
}
util.assert(res.ok != null);
return res.ok;
diff --git a/cli/tsc/99_main_compiler.js b/cli/tsc/99_main_compiler.js
index 41051f2e0..23e25237a 100644
--- a/cli/tsc/99_main_compiler.js
+++ b/cli/tsc/99_main_compiler.js
@@ -23,6 +23,7 @@ delete Object.prototype.__proto__;
const dispatchJson = window.__bootstrap.dispatchJson;
const util = window.__bootstrap.util;
const errorStack = window.__bootstrap.errorStack;
+ const errors = window.__bootstrap.errors.errors;
function opNow() {
const res = dispatchJson.sendSync("op_now");
@@ -1851,6 +1852,27 @@ delete Object.prototype.__proto__;
throw new Error("Worker runtime already bootstrapped");
}
hasBootstrapped = true;
+ core.registerErrorClass("NotFound", errors.NotFound);
+ core.registerErrorClass("PermissionDenied", errors.PermissionDenied);
+ core.registerErrorClass("ConnectionRefused", errors.ConnectionRefused);
+ core.registerErrorClass("ConnectionReset", errors.ConnectionReset);
+ core.registerErrorClass("ConnectionAborted", errors.ConnectionAborted);
+ core.registerErrorClass("NotConnected", errors.NotConnected);
+ core.registerErrorClass("AddrInUse", errors.AddrInUse);
+ core.registerErrorClass("AddrNotAvailable", errors.AddrNotAvailable);
+ core.registerErrorClass("BrokenPipe", errors.BrokenPipe);
+ core.registerErrorClass("AlreadyExists", errors.AlreadyExists);
+ core.registerErrorClass("InvalidData", errors.InvalidData);
+ core.registerErrorClass("TimedOut", errors.TimedOut);
+ core.registerErrorClass("Interrupted", errors.Interrupted);
+ core.registerErrorClass("WriteZero", errors.WriteZero);
+ core.registerErrorClass("UnexpectedEof", errors.UnexpectedEof);
+ core.registerErrorClass("BadResource", errors.BadResource);
+ core.registerErrorClass("Http", errors.Http);
+ core.registerErrorClass("URIError", URIError);
+ core.registerErrorClass("TypeError", TypeError);
+ core.registerErrorClass("Other", Error);
+ core.registerErrorClass("Busy", errors.Busy);
globalThis.__bootstrap = undefined;
runtimeStart("TS");
}
diff --git a/core/core.js b/core/core.js
index b3c0ddc13..5f9d6f981 100644
--- a/core/core.js
+++ b/core/core.js
@@ -38,6 +38,7 @@ SharedQueue Binary Layout
let initialized = false;
let opsCache = {};
+ const errorMap = {};
function maybeInit() {
if (!initialized) {
@@ -187,11 +188,26 @@ SharedQueue Binary Layout
return send(opsCache[opName], control, ...zeroCopy);
}
+ function registerErrorClass(errorName, errorClass) {
+ if (typeof errorMap[errorName] !== "undefined") {
+ throw new TypeError(`Error class for "${errorName}" already registered`);
+ }
+ errorMap[errorName] = errorClass;
+ }
+
+ function getErrorClass(errorName) {
+ const errorClass = errorMap[errorName];
+ assert(errorClass);
+ return errorClass;
+ }
+
Object.assign(window.Deno.core, {
setAsyncHandler,
dispatch: send,
dispatchByName: dispatch,
ops,
+ registerErrorClass,
+ getErrorClass,
// sharedQueue is private but exposed for testing.
sharedQueue: {
MAX_RECORDS,