Skip to content

Commit 8cce4f1

Browse files
committed
refactor: Clean up error handling
1 parent 7343a7e commit 8cce4f1

File tree

2 files changed

+38
-37
lines changed

2 files changed

+38
-37
lines changed

cli/src/main.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use andromeda_runtime::{
66
recommended_builtins, recommended_eventloop_handler, recommended_extensions,
77
};
88
use clap::{Parser as ClapParser, Subcommand};
9-
use nova_vm::engine::context::Bindable;
109
/// A JavaScript runtime
1110
#[derive(Debug, ClapParser)]
1211
#[command(name = "andromeda")]
@@ -50,24 +49,32 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
5049
no_strict,
5150
paths,
5251
} => {
53-
let mut runtime = Runtime::new(RuntimeConfig {
52+
let runtime = Runtime::new(RuntimeConfig {
5453
no_strict,
5554
paths,
5655
verbose,
5756
extensions: recommended_extensions(),
5857
builtins: recommended_builtins(),
5958
eventloop_handler: recommended_eventloop_handler,
6059
});
61-
let runtime_result = runtime.run(|agent, gc, error| {
62-
eprintln!(
63-
"Uncaught exception: {}",
64-
error.value().unbind().string_repr(agent, gc).as_str(agent)
65-
);
66-
});
60+
let mut runtime_output = runtime.run();
6761

68-
if let Ok(result) = runtime_result {
69-
if verbose {
70-
println!("{:?}", result);
62+
match runtime_output.result {
63+
Ok(result) => {
64+
if verbose {
65+
println!("{:?}", result);
66+
}
67+
}
68+
Err(error) => {
69+
runtime_output
70+
.agent
71+
.run_in_realm(&runtime_output.realm_root, |agent, gc| {
72+
eprintln!(
73+
"Uncaught exception: {}",
74+
error.value().string_repr(agent, gc).as_str(agent)
75+
);
76+
std::process::exit(1);
77+
})
7178
}
7279
}
7380
}

core/src/runtime.rs

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use nova_vm::{
1111
builtins::promise_objects::promise_abstract_operations::promise_capability_records::PromiseCapability,
1212
execution::{
1313
Agent, JsResult,
14-
agent::{GcAgent, HostHooks, Job, JsError, Options, RealmRoot},
14+
agent::{GcAgent, HostHooks, Job, Options, RealmRoot},
1515
},
1616
scripts_and_modules::script::{parse_script, script_evaluation},
1717
types::{self, Object, Value},
@@ -130,10 +130,7 @@ impl<UserMacroTask> Runtime<UserMacroTask> {
130130
}
131131

132132
/// Run the Runtime with the specified configuration.
133-
pub fn run(
134-
&mut self,
135-
mut error_handler: impl FnMut(&mut Agent, GcScope, JsError<'static>),
136-
) -> JsResult<Value<'static>> {
133+
pub fn run(mut self) -> RuntimeOutput {
137134
// Load the builtins js sources
138135
self.agent.run_in_realm(&self.realm_root, |agent, mut gc| {
139136
for builtin in &self.config.builtins {
@@ -157,13 +154,13 @@ impl<UserMacroTask> Runtime<UserMacroTask> {
157154
}
158155
});
159156

160-
let mut final_result = Value::<'static>::Null;
157+
let mut result = JsResult::Ok(Value::Null);
161158

162159
// Fetch the runtime mod.ts file using a macro and add it to the paths
163160
for path in &self.config.paths {
164161
let file = std::fs::read_to_string(path).unwrap();
165162

166-
final_result = self.agent.run_in_realm(&self.realm_root, |agent, mut gc| {
163+
result = self.agent.run_in_realm(&self.realm_root, |agent, mut gc| {
167164
let source_text = types::String::from_string(agent, file, gc.nogc());
168165
let realm = agent.current_realm(gc.nogc());
169166

@@ -179,28 +176,15 @@ impl<UserMacroTask> Runtime<UserMacroTask> {
179176
Err(errors) => exit_with_parse_errors(errors, path, source_text.as_str(agent)),
180177
};
181178

182-
let res = script_evaluation(agent, script.unbind(), gc.reborrow())
183-
.map(move |v| v.unbind())
184-
.unbind();
185-
if let Err(err) = res {
186-
error_handler(agent, gc.reborrow(), err);
187-
}
188-
res
189-
})?;
179+
script_evaluation(agent, script.unbind(), gc.reborrow()).unbind()
180+
});
190181
}
191182

192183
loop {
193184
while let Some(job) = self.host_hooks.pop_promise_job() {
194-
self.agent.run_in_realm(&self.realm_root, |agent, mut gc| {
195-
let res = job
196-
.run(agent, gc.reborrow())
197-
.map(move |v| v.unbind())
198-
.unbind();
199-
if let Err(err) = res {
200-
error_handler(agent, gc, err);
201-
}
202-
res
203-
})?;
185+
result = self.agent.run_in_realm(&self.realm_root, |agent, mut gc| {
186+
job.run(agent, gc.reborrow()).unbind().map(|_| Value::Null)
187+
});
204188
}
205189

206190
// If both the microtasks and macrotasks queues are empty we can end the event loop
@@ -211,7 +195,11 @@ impl<UserMacroTask> Runtime<UserMacroTask> {
211195
self.handle_macro_task();
212196
}
213197

214-
Ok(final_result)
198+
RuntimeOutput {
199+
agent: self.agent,
200+
realm_root: self.realm_root,
201+
result,
202+
}
215203
}
216204

217205
// Listen for pending macro tasks and resolve one by one
@@ -241,3 +229,9 @@ impl<UserMacroTask> Runtime<UserMacroTask> {
241229
}
242230
}
243231
}
232+
233+
pub struct RuntimeOutput {
234+
pub agent: GcAgent,
235+
pub realm_root: RealmRoot,
236+
pub result: JsResult<'static, Value<'static>>,
237+
}

0 commit comments

Comments
 (0)