1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

Encode op errors as strings instead of numbers (#6977)

This commit is contained in:
Bartek Iwańczuk 2020-08-07 22:47:18 +02:00 committed by GitHub
parent 479164d287
commit 59ca66a207
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 197 additions and 293 deletions

View file

@ -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");
}
}

View file

@ -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,
})
}

View file

@ -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()

View file

@ -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)))
}

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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,

View file

@ -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");
});

View file

@ -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);

View file

@ -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;

View file

@ -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");
}

View file

@ -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,