1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -05:00

fix(compile): disable source mapping of errors (#8581)

This commit disables source mapping of errors
for standalone binaries. Since applying source
maps relies on using file fetcher infrastructure
it's not feasible to use it for standalone binaries
that are not supposed to use that infrastructure.
This commit is contained in:
Bartek Iwańczuk 2020-12-01 23:33:44 +01:00 committed by GitHub
parent 6e03917b51
commit f49d955601
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 88 additions and 15 deletions

View file

@ -13,11 +13,18 @@ use deno_core::OpState;
use deno_core::ZeroCopyBuf; use deno_core::ZeroCopyBuf;
use std::env; use std::env;
pub fn init(rt: &mut deno_core::JsRuntime, main_module: ModuleSpecifier) { type ApplySourceMaps = bool;
pub fn init(
rt: &mut deno_core::JsRuntime,
main_module: ModuleSpecifier,
apply_source_maps: bool,
) {
{ {
let op_state = rt.op_state(); let op_state = rt.op_state();
let mut state = op_state.borrow_mut(); let mut state = op_state.borrow_mut();
state.put::<ModuleSpecifier>(main_module); state.put::<ModuleSpecifier>(main_module);
state.put::<ApplySourceMaps>(apply_source_maps);
} }
super::reg_json_sync(rt, "op_start", op_start); super::reg_json_sync(rt, "op_start", op_start);
super::reg_json_sync(rt, "op_main_module", op_main_module); super::reg_json_sync(rt, "op_main_module", op_main_module);
@ -29,10 +36,12 @@ fn op_start(
_args: Value, _args: Value,
_zero_copy: &mut [ZeroCopyBuf], _zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, AnyError> { ) -> Result<Value, AnyError> {
let apply_source_maps = *state.borrow::<ApplySourceMaps>();
let gs = &super::program_state(state); let gs = &super::program_state(state);
Ok(json!({ Ok(json!({
"args": gs.flags.argv.clone(), "args": gs.flags.argv.clone(),
"applySourceMaps": apply_source_maps,
"debugFlag": gs.flags.log_level.map_or(false, |l| l == log::Level::Debug), "debugFlag": gs.flags.log_level.map_or(false, |l| l == log::Level::Debug),
"denoVersion": version::deno(), "denoVersion": version::deno(),
"noColor": !colors::use_color(), "noColor": !colors::use_color(),

View file

@ -160,7 +160,12 @@ delete Object.prototype.__proto__;
version.setVersions(s.denoVersion, s.v8Version, s.tsVersion); version.setVersions(s.denoVersion, s.v8Version, s.tsVersion);
build.setBuildInfo(s.target); build.setBuildInfo(s.target);
util.setLogDebug(s.debugFlag, source); util.setLogDebug(s.debugFlag, source);
// TODO(bartlomieju): a very crude way to disable
// source mapping of errors. This condition is true
// only for compiled standalone binaries.
if (s.applySourceMaps) {
errorStack.setPrepareStackTrace(Error); errorStack.setPrepareStackTrace(Error);
}
return s; return s;
} }

View file

@ -117,6 +117,7 @@ async fn run(source_code: String, args: Vec<String>) -> Result<(), AnyError> {
main_module.clone(), main_module.clone(),
permissions, permissions,
module_loader, module_loader,
None,
); );
worker.execute_module(&main_module).await?; worker.execute_module(&main_module).await?;
worker.execute("window.dispatchEvent(new Event('load'))")?; worker.execute("window.dispatchEvent(new Event('load'))")?;

View file

@ -4600,6 +4600,42 @@ fn standalone_args() {
assert_eq!(output.stdout, b"foo\n--bar\n--unstable\n"); assert_eq!(output.stdout, b"foo\n--bar\n--unstable\n");
} }
#[test]
fn standalone_error() {
let dir = TempDir::new().expect("tempdir fail");
let exe = if cfg!(windows) {
dir.path().join("error.exe")
} else {
dir.path().join("error")
};
let output = util::deno_cmd()
.current_dir(util::root_path())
.arg("compile")
.arg("--unstable")
.arg("--output")
.arg(&exe)
.arg("./cli/tests/standalone_error.ts")
.stdout(std::process::Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(output.status.success());
let output = Command::new(exe)
.env("NO_COLOR", "1")
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(!output.status.success());
assert_eq!(output.stdout, b"");
let expected_stderr = "error: Error: boom!\n at boom (file://$deno$/bundle.js:2:11)\n at foo (file://$deno$/bundle.js:5:5)\n at file://$deno$/bundle.js:7:1\n";
let stderr = String::from_utf8(output.stderr).unwrap();
assert_eq!(stderr, expected_stderr);
}
#[test] #[test]
fn standalone_no_module_load() { fn standalone_no_module_load() {
let dir = TempDir::new().expect("tempdir fail"); let dir = TempDir::new().expect("tempdir fail");

View file

@ -0,0 +1,9 @@
function boom() {
throw new Error("boom!");
}
function foo() {
boom();
}
foo();

View file

@ -195,7 +195,7 @@ impl WebWorker {
} }
ops::web_worker::init(js_runtime, sender.clone(), handle); ops::web_worker::init(js_runtime, sender.clone(), handle);
ops::runtime::init(js_runtime, main_module); ops::runtime::init(js_runtime, main_module, true);
ops::fetch::init(js_runtime, program_state.flags.ca_file.as_deref()); ops::fetch::init(js_runtime, program_state.flags.ca_file.as_deref());
ops::timers::init(js_runtime); ops::timers::init(js_runtime);
ops::worker_host::init(js_runtime, Some(sender)); ops::worker_host::init(js_runtime, Some(sender));

View file

@ -15,6 +15,7 @@ use deno_core::error::AnyError;
use deno_core::futures::future::poll_fn; use deno_core::futures::future::poll_fn;
use deno_core::futures::future::FutureExt; use deno_core::futures::future::FutureExt;
use deno_core::url::Url; use deno_core::url::Url;
use deno_core::JsErrorCreateFn;
use deno_core::JsRuntime; use deno_core::JsRuntime;
use deno_core::ModuleId; use deno_core::ModuleId;
use deno_core::ModuleLoader; use deno_core::ModuleLoader;
@ -48,15 +49,6 @@ impl MainWorker {
let module_loader = let module_loader =
CliModuleLoader::new(program_state.maybe_import_map.clone()); CliModuleLoader::new(program_state.maybe_import_map.clone());
Self::from_options(program_state, main_module, permissions, module_loader)
}
pub fn from_options(
program_state: &Arc<ProgramState>,
main_module: ModuleSpecifier,
permissions: Permissions,
module_loader: Rc<dyn ModuleLoader>,
) -> Self {
let global_state_ = program_state.clone(); let global_state_ = program_state.clone();
let js_error_create_fn = Box::new(move |core_js_error| { let js_error_create_fn = Box::new(move |core_js_error| {
@ -65,10 +57,30 @@ impl MainWorker {
PrettyJsError::create(source_mapped_error) PrettyJsError::create(source_mapped_error)
}); });
Self::from_options(
program_state,
main_module,
permissions,
module_loader,
Some(js_error_create_fn),
)
}
pub fn from_options(
program_state: &Arc<ProgramState>,
main_module: ModuleSpecifier,
permissions: Permissions,
module_loader: Rc<dyn ModuleLoader>,
js_error_create_fn: Option<Box<JsErrorCreateFn>>,
) -> Self {
// TODO(bartlomieju): this is hacky way to not apply source
// maps in JS
let apply_source_maps = js_error_create_fn.is_some();
let mut js_runtime = JsRuntime::new(RuntimeOptions { let mut js_runtime = JsRuntime::new(RuntimeOptions {
module_loader: Some(module_loader), module_loader: Some(module_loader),
startup_snapshot: Some(js::deno_isolate_init()), startup_snapshot: Some(js::deno_isolate_init()),
js_error_create_fn: Some(js_error_create_fn), js_error_create_fn,
get_error_class_fn: Some(&crate::errors::get_error_class_name), get_error_class_fn: Some(&crate::errors::get_error_class_name),
..Default::default() ..Default::default()
}); });
@ -105,7 +117,7 @@ impl MainWorker {
op_state.put::<Permissions>(permissions); op_state.put::<Permissions>(permissions);
} }
ops::runtime::init(js_runtime, main_module); ops::runtime::init(js_runtime, main_module, apply_source_maps);
ops::fetch::init(js_runtime, program_state.flags.ca_file.as_deref()); ops::fetch::init(js_runtime, program_state.flags.ca_file.as_deref());
ops::timers::init(js_runtime); ops::timers::init(js_runtime);
ops::worker_host::init(js_runtime, None); ops::worker_host::init(js_runtime, None);

View file

@ -60,6 +60,7 @@ pub use crate::resources2::Resource;
pub use crate::resources2::ResourceId; pub use crate::resources2::ResourceId;
pub use crate::resources2::ResourceTable2; pub use crate::resources2::ResourceTable2;
pub use crate::runtime::GetErrorClassFn; pub use crate::runtime::GetErrorClassFn;
pub use crate::runtime::JsErrorCreateFn;
pub use crate::runtime::JsRuntime; pub use crate::runtime::JsRuntime;
pub use crate::runtime::RuntimeOptions; pub use crate::runtime::RuntimeOptions;
pub use crate::runtime::Snapshot; pub use crate::runtime::Snapshot;

View file

@ -53,7 +53,7 @@ pub enum Snapshot {
Boxed(Box<[u8]>), Boxed(Box<[u8]>),
} }
type JsErrorCreateFn = dyn Fn(JsError) -> AnyError; pub type JsErrorCreateFn = dyn Fn(JsError) -> AnyError;
pub type GetErrorClassFn = pub type GetErrorClassFn =
&'static dyn for<'e> Fn(&'e AnyError) -> &'static str; &'static dyn for<'e> Fn(&'e AnyError) -> &'static str;