Repository: awslabs/llrt
File: llrt_core/src/vm.rs (Rust)

Code before:
            })
            .await;
    }

    pub async fn run_file(&self, filename: impl AsRef<str>, strict: bool, global: bool) {
        let source = [
            r#"import(""#,
            &filename.as_ref().replace('\\', "/"),
            r#"").catch((e) => {{console.error(e);process.exit(1)}})"#,
        ]
        .concat();

        self.run(source, strict, global).await;
    }

    pub async fn run_repl(&self) {
        self.ctx
            .with(|ctx| -> Result<()> {
                let mut input = String::new();
                println!("Welcome to llrt v{}", VERSION);
                loop {
                    print!("> ");
                    std::io::Write::flush(&mut std::io::stdout())?;
                    std::io::stdin().read_line(&mut input)?;
                    match ctx.eval::<Value, _>(input.as_bytes()) {
                        Ok(v) => console::log_std_out(
                            &ctx.clone(),
                            Rest(vec![v]),
                            console::LogLevel::Info,
                        )
                        .expect("REPL failed to write log"),
                        Err(err) => {
                            let mut error_str = String::new();
                            write!(error_str, "Error: {:?}", err).unwrap();
                            if console::log_std_err(
                                &ctx.clone(),
                                Rest(vec![err.into_value(&ctx.clone())?]),
                                console::LogLevel::Fatal,
                            )
                            .is_err()
                            {
                                eprintln!("{}", error_str);
                            }
                        },
                    };
                    input.clear();
                }
            })
            .await
            .expect("Failed to run REPL")
    }

Review comment (suggestion):
Call `pub fn format` in console instead to get the formated string back. Then do `println` or `eprintln` (for exception) with that string.

Code after:
            .await;
    }

    pub async fn run_file(&self, filename: impl AsRef<str>, strict: bool, global: bool) {
        let source = [
            r#"import(""#,
            &filename.as_ref().replace('\\', "/"),
            r#"").catch((e) => {{console.error(e);process.exit(1)}})"#,
        ]
        .concat();

        self.run(source, strict, global).await;
    }

    pub async fn run_repl(&self) {
        run_repl(&self.ctx).await;
    }

    pub async fn run<S: Into<Vec<u8>> + Send>(&self, source: S, strict: bool, global: bool) {
        self.run_with(|ctx| {
            let mut options = EvalOptions::default();
            options.strict = strict;
            options.promise = true;
            options.global = global;
            let _ = ctx.eval_with_options::<Value, _>(source, options)?;
            Ok::<_, Error>(())
        })
        .await;
    }

    pub fn print_error_and_exit<'js>(ctx: &Ctx<'js>, err: CaughtError<'js>) -> ! {
        let mut error_str = String::new();
        write!(error_str, "Error: {:?}", err).unwrap();
        if let Ok(error) = err.into_value(ctx) {
            if console::log_std_err(ctx, Rest(vec![error.clone()]), console::LogLevel::Fatal)
                .is_err()
            {
                eprintln!("{}", error_str);
            };
            if cfg!(test) {
                panic!("{:?}", error);
            } else {
                exit(1)
            }
        } else if cfg!(test) {
            panic!("{}", error_str);
        } else {
            eprintln!("{}", error_str);
            exit(1)
        };
    }