Skip to content

Commit c29cd35

Browse files
authored
Stop using process:exit for error code handling (software-mansion#1652)
1 parent 57dd424 commit c29cd35

File tree

6 files changed

+33
-22
lines changed

6 files changed

+33
-22
lines changed

scarb/src/bin/scarb/commands/fmt.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use anyhow::Result;
2+
use std::process::ExitCode;
23

34
use crate::args::{EmitTarget, FmtArgs};
45
use crate::errors::error_with_exit_code;
@@ -35,7 +36,7 @@ pub fn run(args: FmtArgs, config: &Config) -> Result<()> {
3536
)? {
3637
Ok(())
3738
} else {
38-
error_with_exit_code(1)
39+
error_with_exit_code(ExitCode::FAILURE)
3940
}
4041
}
4142

scarb/src/bin/scarb/commands/run.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::args::ScriptsRunnerArgs;
2+
use crate::errors::ErrorWithExitCode;
13
use anyhow::{anyhow, Result};
24
use indoc::formatdoc;
35
use itertools::Itertools;
@@ -10,9 +12,7 @@ use smol_str::SmolStr;
1012
use std::collections::BTreeMap;
1113
use std::ffi::OsString;
1214
use std::fmt::Write;
13-
14-
use crate::args::ScriptsRunnerArgs;
15-
use crate::errors::ErrorWithExitCode;
15+
use std::process::ExitCode;
1616

1717
#[tracing::instrument(skip_all, level = "info")]
1818
pub fn run(args: ScriptsRunnerArgs, config: &Config) -> Result<()> {
@@ -79,8 +79,9 @@ fn build_exit_error(errors: Vec<anyhow::Error>) -> Result<()> {
7979
err.downcast_ref::<ScriptExecutionError>()
8080
.map(|err| err.exit_code)
8181
})
82-
.find(|exit_code| *exit_code != 0)
83-
.unwrap_or(1);
82+
.take(1)
83+
.collect_vec();
84+
let exit_code = exit_code.first().cloned().unwrap_or(ExitCode::FAILURE);
8485
let msg = errors
8586
.into_iter()
8687
.map(|err| err.to_string())

scarb/src/bin/scarb/errors.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
use anyhow::Result;
2+
use std::process::ExitCode;
23
use thiserror::Error;
34

45
/// The ErrorWithExitCode is the error type used at Scarb's CLI-layer.
56
#[derive(Error, Debug)]
6-
#[error("ErrorWithExitCode exit_code: {exit_code}")]
7+
#[error("ErrorWithExitCode exit_code: {:?}", exit_code)]
78
pub struct ErrorWithExitCode {
89
/// The error to display. This can be `None` in rare cases to exit with a
910
/// code without displaying a message.
1011
#[source]
1112
pub source: Option<anyhow::Error>,
1213
/// The process exit code.
13-
pub exit_code: i32,
14+
pub exit_code: ExitCode,
1415
}
1516

1617
impl ErrorWithExitCode {
17-
pub fn new(error: anyhow::Error, code: i32) -> Self {
18+
pub fn new(error: anyhow::Error, code: ExitCode) -> Self {
1819
Self {
1920
source: Some(error),
2021
exit_code: code,
2122
}
2223
}
2324

24-
pub fn code(code: i32) -> Self {
25+
pub fn code(code: ExitCode) -> Self {
2526
Self {
2627
source: None,
2728
exit_code: code,
@@ -31,16 +32,16 @@ impl ErrorWithExitCode {
3132

3233
impl From<anyhow::Error> for ErrorWithExitCode {
3334
fn from(err: anyhow::Error) -> ErrorWithExitCode {
34-
ErrorWithExitCode::new(err, 1)
35+
ErrorWithExitCode::new(err, ExitCode::FAILURE)
3536
}
3637
}
3738

3839
impl From<std::io::Error> for ErrorWithExitCode {
3940
fn from(err: std::io::Error) -> ErrorWithExitCode {
40-
ErrorWithExitCode::new(err.into(), 1)
41+
ErrorWithExitCode::new(err.into(), ExitCode::FAILURE)
4142
}
4243
}
4344

44-
pub fn error_with_exit_code<T>(code: i32) -> Result<T> {
45+
pub fn error_with_exit_code<T>(code: ExitCode) -> Result<T> {
4546
Err(ErrorWithExitCode::code(code).into())
4647
}

scarb/src/bin/scarb/main.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::env;
2+
use std::process::ExitCode;
23
use std::str::FromStr;
34

45
use anyhow::{Error, Result};
@@ -19,7 +20,7 @@ mod commands;
1920
mod errors;
2021
mod interactive;
2122

22-
fn main() {
23+
fn main() -> ExitCode {
2324
let args = ScarbArgs::parse();
2425

2526
// Pre-create Ui used in logging & error reporting, because we will move `args` to `cli_main`.
@@ -39,25 +40,27 @@ fn main() {
3940
.init();
4041

4142
if let Err(err) = cli_main(args) {
42-
exit_with_error(err, &ui);
43+
return exit_with_error(err, &ui);
4344
}
45+
46+
ExitCode::SUCCESS
4447
}
4548

46-
fn exit_with_error(err: Error, ui: &Ui) {
49+
fn exit_with_error(err: Error, ui: &Ui) -> ExitCode {
4750
debug!("exit_with_error; err={:?}", err);
4851

4952
if let Some(ErrorWithExitCode { source, exit_code }) = err.downcast_ref::<ErrorWithExitCode>() {
5053
if let Some(source_err) = source {
5154
ui.anyhow(source_err);
5255
}
53-
std::process::exit(*exit_code);
56+
*exit_code
5457
} else if let Some(ScriptExecutionError { exit_code }) =
5558
err.downcast_ref::<ScriptExecutionError>()
5659
{
57-
std::process::exit(*exit_code);
60+
*exit_code
5861
} else {
5962
ui.anyhow(&err);
60-
std::process::exit(1);
63+
ExitCode::FAILURE
6164
}
6265
}
6366

scarb/src/core/errors.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1+
use std::process::ExitCode;
12
use thiserror::Error;
23

34
#[derive(Debug, Error)]
4-
#[error("script failed with exit code: {exit_code}")]
5+
#[error("script failed with exit code: {:?}", exit_code)]
56
pub struct ScriptExecutionError {
67
/// The process exit code.
7-
pub exit_code: i32,
8+
pub exit_code: ExitCode,
89
}
910

1011
impl ScriptExecutionError {
11-
pub fn new(exit_code: i32) -> Self {
12+
pub fn new(exit_code: ExitCode) -> Self {
1213
Self { exit_code }
1314
}
1415
}

scarb/src/ops/scripts.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::collections::HashMap;
22
use std::env;
33
use std::ffi::OsString;
4+
use std::process::ExitCode;
45
use std::rc::Rc;
56

67
use anyhow::Result;
@@ -56,6 +57,9 @@ pub fn execute_script(
5657
));
5758

5859
if exit_code != 0 {
60+
let exit_code: ExitCode = u8::try_from(exit_code)
61+
.map(Into::into)
62+
.unwrap_or(ExitCode::FAILURE);
5963
Err(ScriptExecutionError::new(exit_code).into())
6064
} else {
6165
Ok(())

0 commit comments

Comments
 (0)