Skip to content

Commit f42ffc9

Browse files
author
Alexander Weber
committed
error handling workover
1 parent 6bab812 commit f42ffc9

8 files changed

Lines changed: 138 additions & 112 deletions

File tree

.complate/config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ templates:
3636
e.echo:
3737
check:
3838
text: Select the components that are affected
39-
separator: "\n"
39+
separator: ", "
4040
options:
4141
alpha:
4242
display: alpha
@@ -46,4 +46,4 @@ templates:
4646
display: bravo
4747
value:
4848
shell: printf bravo
49-
49+

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
"backend+cli",
44
"backend+ui",
55
]
6-
}
6+
}

src/args/mod.rs

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::io::Result;
1+
use std::result::Result;
22

33
pub struct CallArgs {
44
pub privileges: Privilege,
@@ -7,24 +7,18 @@ pub struct CallArgs {
77

88
impl CallArgs {
99
#[allow(clippy::single_match)]
10-
pub async fn validate(&self) -> Result<()> {
10+
pub async fn validate(&self) -> Result<(), Box<dyn std::error::Error>> {
1111
match self.privileges {
1212
Privilege::Normal => match &self.command {
1313
Command::Render(args) => {
1414
match args.backend {
1515
#[cfg(feature = "backend+ui")]
16-
Backend::UI => return Err(std::io::Error::new(
17-
std::io::ErrorKind::Other,
18-
"can not use backend+ui without experimental features being activated",
19-
)),
16+
Backend::UI => return Err(Box::new(crate::error::NeedExperimentalFlag::default())),
2017
#[cfg(feature = "backend+cli")]
2118
Backend::CLI => {}
2219
};
2320
if args.value_overrides.len() > 0 {
24-
return Err(std::io::Error::new(
25-
std::io::ErrorKind::Other,
26-
"value overrides is an experimental feature and needs the respective flag to be active",
27-
));
21+
return Err(Box::new(crate::error::NeedExperimentalFlag::default()));
2822
}
2923
#[allow(unreachable_code)]
3024
Ok(())
@@ -70,7 +64,7 @@ pub enum Backend {
7064
pub struct ClapArgumentLoader {}
7165

7266
impl ClapArgumentLoader {
73-
pub async fn load_from_cli() -> std::io::Result<CallArgs> {
67+
pub async fn load_from_cli() -> std::result::Result<CallArgs, Box<dyn std::error::Error>> {
7468
let mut backend_values = Vec::new();
7569
if cfg!(feature = "backend+cli") {
7670
backend_values.push("cli");
@@ -159,10 +153,7 @@ impl ClapArgumentLoader {
159153
let config_param = x.value_of("config").unwrap();
160154
std::fs::read_to_string(config_param.to_owned())?
161155
} else {
162-
return Err(std::io::Error::new(
163-
std::io::ErrorKind::Other,
164-
"configuration not specified",
165-
));
156+
return Err(Box::new(crate::error::Failed::new("configuration unspecified")));
166157
};
167158

168159
let template = if x.is_present("template") {
@@ -197,10 +188,7 @@ impl ClapArgumentLoader {
197188
#[cfg(feature = "backend+ui")]
198189
"ui" => Backend::UI,
199190
_ => {
200-
return Err(std::io::Error::new(
201-
std::io::ErrorKind::Other,
202-
"unknown backend configuration",
203-
))
191+
return Err(Box::new(crate::error::Failed::new("no backend specified")))
204192
}
205193
},
206194
#[cfg(feature = "backend+cli")]
@@ -221,10 +209,7 @@ impl ClapArgumentLoader {
221209
}),
222210
})
223211
}
224-
None => Err(std::io::Error::new(
225-
std::io::ErrorKind::Other,
226-
"could not resolve subcommand",
227-
)),
212+
None => Err(Box::new(crate::error::UnknownCommand::default())),
228213
}
229214
}
230215
}

src/error.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
macro_rules! make_error {
2+
($name:ident) => {
3+
#[derive(Debug, Clone)]
4+
/// An error type.
5+
pub struct $name {
6+
details: String,
7+
}
8+
9+
impl $name {
10+
pub fn default() -> Self {
11+
Self::new("")
12+
}
13+
14+
/// Error type constructor.
15+
pub fn new(details: &str) -> Self {
16+
Self {
17+
details: details.to_owned(),
18+
}
19+
}
20+
}
21+
22+
impl std::fmt::Display for $name {
23+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24+
f.write_str(&self.details)
25+
}
26+
}
27+
28+
impl std::error::Error for $name {}
29+
};
30+
}
31+
32+
make_error!(Failed);
33+
make_error!(NeedExperimentalFlag);
34+
make_error!(UnknownCommand);
35+
make_error!(UserAbort);
36+
make_error!(NoShellTrust);

src/main.rs

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,67 +2,69 @@ include!("check_features.rs");
22

33
use futures::executor::block_on;
44

5-
use std::io::{Result, Write};
5+
use std::io::Write;
6+
use std::result::Result;
67

78
pub mod args;
89
pub mod config;
910
pub mod render;
11+
pub mod error;
1012

1113
async fn default_config() -> String {
1214
r###"version: 0.10
13-
templates:
14-
one:
15-
content:
16-
file: ./.complate/templates/arbitraty-template-file.tpl
17-
values:
18-
a.summary:
19-
static: "random summary"
20-
two:
21-
content:
22-
inline: |-
23-
{{ a.alpha }}
24-
{{ b.bravo }}
25-
{{ c.charlie }}
26-
{{ d.delta }}
27-
{{ e.echo }}
28-
values:
29-
a.alpha:
30-
prompt: "alpha"
31-
b.bravo:
32-
shell: "printf bravo"
33-
c.charlie:
34-
static: "charlie"
35-
d.delta:
36-
select:
37-
text: Select the version level that shall be incremented
38-
options:
39-
alpha:
40-
display: alpha
41-
value:
42-
static: alpha
43-
bravo:
44-
display: bravo
45-
value:
46-
shell: printf bravo
47-
e.echo:
48-
check:
49-
text: Select the components that are affected
50-
separator: ", "
51-
options:
52-
alpha:
53-
display: alpha
54-
value:
55-
static: alpha
56-
bravo:
57-
display: bravo
58-
value:
59-
shell: printf bravo
15+
templates:
16+
one:
17+
content:
18+
file: ./.complate/templates/arbitraty-template-file.tpl
19+
values:
20+
a.summary:
21+
static: "random summary"
22+
two:
23+
content:
24+
inline: |-
25+
{{ a.alpha }}
26+
{{ b.bravo }}
27+
{{ c.charlie }}
28+
{{ d.delta }}
29+
{{ e.echo }}
30+
values:
31+
a.alpha:
32+
prompt: "alpha"
33+
b.bravo:
34+
shell: "printf bravo"
35+
c.charlie:
36+
static: "charlie"
37+
d.delta:
38+
select:
39+
text: Select the version level that shall be incremented
40+
options:
41+
alpha:
42+
display: alpha
43+
value:
44+
static: alpha
45+
bravo:
46+
display: bravo
47+
value:
48+
shell: printf bravo
49+
e.echo:
50+
check:
51+
text: Select the components that are affected
52+
separator: ", "
53+
options:
54+
alpha:
55+
display: alpha
56+
value:
57+
static: alpha
58+
bravo:
59+
display: bravo
60+
value:
61+
shell: printf bravo
6062
6163
"###
6264
.to_owned()
6365
}
6466

65-
async fn async_main() -> Result<()> {
67+
async fn async_main() -> Result<(), Box<dyn std::error::Error>> {
6668
let cmd = crate::args::ClapArgumentLoader::load_from_cli().await?;
6769
cmd.validate().await?;
6870

@@ -80,6 +82,6 @@ async fn async_main() -> Result<()> {
8082
}
8183
}
8284

83-
fn main() -> Result<()> {
85+
fn main() -> Result<(), Box<dyn std::error::Error>> {
8486
block_on(async_main())
8587
}

src/render/cli.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::UserInput;
22
use async_trait::async_trait;
3-
use std::io::Result;
3+
use std::result::Result;
44

55
pub struct CLIBackend<'a> {
66
shell_trust: &'a super::ShellTrust,
@@ -14,22 +14,25 @@ impl<'a> CLIBackend<'a> {
1414

1515
#[async_trait]
1616
impl<'a> UserInput for CLIBackend<'a> {
17-
async fn prompt(&self, text: &str) -> Result<String> {
18-
dialoguer::Input::new()
17+
async fn prompt(&self, text: &str) -> Result<String, Box<dyn std::error::Error>> {
18+
match dialoguer::Input::new()
1919
.allow_empty(true)
2020
.with_prompt(text)
21-
.interact()
21+
.interact() {
22+
Ok(res) => Ok(res),
23+
Err(_) => Err(Box::new(crate::error::Failed::default()))
24+
}
2225
}
2326

24-
async fn shell(&self, command: &str, shell_trust: &super::ShellTrust) -> Result<String> {
27+
async fn shell(&self, command: &str, shell_trust: &super::ShellTrust) -> Result<String, Box<dyn std::error::Error>> {
2528
super::shell(command, shell_trust, &super::Backend::CLI).await
2629
}
2730

2831
async fn select(
2932
&self,
3033
prompt: &str,
3134
options: &std::collections::BTreeMap<String, super::Option>,
32-
) -> Result<String> {
35+
) -> Result<String, Box<dyn std::error::Error>> {
3336
let keys = options.keys().cloned().collect::<Vec<String>>();
3437
let display_vals = options
3538
.values()
@@ -53,7 +56,7 @@ impl<'a> UserInput for CLIBackend<'a> {
5356
prompt: &str,
5457
separator: &str,
5558
options: &std::collections::BTreeMap<String, super::Option>,
56-
) -> Result<String> {
59+
) -> Result<String, Box<dyn std::error::Error>> {
5760
let keys = options.keys().cloned().collect::<Vec<String>>();
5861
let display_vals = options
5962
.values()

0 commit comments

Comments
 (0)