Skip to content

Commit ba61d59

Browse files
committed
Merge branch 'fix/unify-errors' into development
* fix/unify-errors: add gems docs use exect version update message remove config error fix default projectname fix input name
2 parents b713107 + e5257bd commit ba61d59

File tree

8 files changed

+123
-53
lines changed

8 files changed

+123
-53
lines changed

crates/cli/src/deploy/config.rs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ use crate::{
44
};
55
use git2::{Cred, CredentialType, Error};
66
use serde::{Deserialize, Serialize};
7-
use smbcloud_model::{account::User, project::Project};
7+
use smbcloud_model::{
8+
account::User,
9+
error_codes::{ErrorCode, ErrorResponse},
10+
project::Project,
11+
};
812
use smbcloud_networking::environment::Environment;
913
use smbcloud_networking_project::crud_project_read::get_project;
1014
use spinners::Spinner;
1115
use std::{fs, path::Path};
12-
use thiserror::Error;
1316

14-
pub(crate) async fn check_config(env: Environment) -> Result<Config, ConfigError> {
17+
pub(crate) async fn check_config(env: Environment) -> Result<Config, ErrorResponse> {
1518
let mut spinner: Spinner = Spinner::new(
1619
spinners::Spinners::SimpleDotsScrolling,
1720
succeed_message("Checking config"),
@@ -31,7 +34,10 @@ pub(crate) async fn check_config(env: Environment) -> Result<Config, ConfigError
3134
}
3235

3336
// Parse toml file
34-
let config_content = fs::read_to_string(config_path).map_err(|_| ConfigError::MissingConfig)?;
37+
let config_content = fs::read_to_string(config_path).map_err(|_| ErrorResponse::Error {
38+
error_code: ErrorCode::MissingConfig,
39+
message: ErrorCode::MissingConfig.message(None).to_string(),
40+
})?;
3541

3642
let config: Config = match toml::from_str(&config_content) {
3743
Ok(value) => value,
@@ -49,15 +55,15 @@ pub(crate) async fn check_config(env: Environment) -> Result<Config, ConfigError
4955
Ok(config)
5056
}
5157

52-
fn handle_config_error() -> Result<Config, ConfigError> {
58+
fn handle_config_error() -> Result<Config, ErrorResponse> {
5359
todo!()
5460
}
5561

5662
pub(crate) async fn check_project(
5763
env: Environment,
5864
access_token: &str,
5965
id: i32,
60-
) -> Result<(), ConfigError> {
66+
) -> Result<(), ErrorResponse> {
6167
let mut spinner: Spinner = Spinner::new(
6268
spinners::Spinners::Hamburger,
6369
succeed_message("Validate project"),
@@ -69,7 +75,10 @@ pub(crate) async fn check_project(
6975
}
7076
Err(_) => {
7177
spinner.stop_and_persist(&fail_symbol(), succeed_message("Project is unsynched"));
72-
Err(ConfigError::ProjectNotFound)
78+
Err(ErrorResponse::Error {
79+
error_code: ErrorCode::ProjectNotFound,
80+
message: ErrorCode::ProjectNotFound.message(None).to_string(),
81+
})
7382
}
7483
}
7584
}
@@ -100,19 +109,3 @@ impl Config {
100109
key_path_str
101110
}
102111
}
103-
104-
#[derive(Error, Debug, PartialEq, Eq)]
105-
pub enum ConfigError {
106-
#[error("Missing token. Make sure you are logged in.")]
107-
MissingToken,
108-
#[error("Missing config file. Please regenerate with 'smb init'.")]
109-
MissingConfig,
110-
#[error("Missing id in repository. Please regenerate with 'smb init'.")]
111-
MissingId,
112-
#[error("Could not find project in your list. Make sure you have access to the project.")]
113-
ProjectNotFound,
114-
#[error("Cancel operation.")]
115-
Cancel,
116-
#[error("Input error.")]
117-
InputError,
118-
}

crates/cli/src/deploy/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ pub async fn process_deploy(env: Environment) -> Result<CommandResult> {
169169
)
170170
.await;
171171
match result {
172-
Ok(_) => println!("Deployment status successfully updated to Done."),
172+
Ok(_) => println!("App is running {}", succeed_symbol()),
173173
Err(update_err) => {
174174
eprintln!("Error updating deployment status to Done: {}", update_err)
175175
}

crates/cli/src/deploy/setup.rs

Lines changed: 71 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
use crate::{
2-
deploy::config::{Config, ConfigError},
3-
ui::highlight,
4-
};
1+
use crate::{deploy::config::Config, ui::highlight};
52
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
63
use regex::Regex;
7-
use smbcloud_model::project::{Project, ProjectCreate};
4+
use smbcloud_model::{
5+
error_codes::{ErrorCode, ErrorResponse},
6+
project::{Project, ProjectCreate},
7+
};
88
use smbcloud_networking::{environment::Environment, get_smb_token};
99
use smbcloud_networking_project::{
1010
crud_project_create::create_project, crud_project_read::get_projects,
1111
};
1212
use std::{env, fs, path::Path};
1313

14-
pub async fn setup_project(env: Environment) -> Result<Config, ConfigError> {
14+
pub async fn setup_project(env: Environment) -> Result<Config, ErrorResponse> {
1515
let path = env::current_dir().ok();
1616
let path_str = path
1717
.as_ref()
@@ -21,20 +21,36 @@ pub async fn setup_project(env: Environment) -> Result<Config, ConfigError> {
2121
let confirm = Confirm::with_theme(&ColorfulTheme::default())
2222
.with_prompt(format!("Setup project in {}? y/n", highlight(&path_str)))
2323
.interact()
24-
.map_err(|_| ConfigError::InputError)?;
24+
.map_err(|_| ErrorResponse::Error {
25+
error_code: ErrorCode::InputError,
26+
message: ErrorCode::InputError.message(None).to_string(),
27+
})?;
2528

2629
if !confirm {
27-
return Err(ConfigError::Cancel);
30+
return Err(ErrorResponse::Error {
31+
error_code: ErrorCode::Cancel,
32+
message: ErrorCode::Cancel.message(None).to_string(),
33+
});
2834
}
2935

3036
let access_token = match get_smb_token(env).await {
3137
Ok(token) => token,
32-
Err(_) => return Err(ConfigError::MissingToken),
38+
Err(_) => {
39+
return Err(ErrorResponse::Error {
40+
error_code: ErrorCode::Unauthorized,
41+
message: ErrorCode::Unauthorized.message(None).to_string(),
42+
})
43+
}
3344
};
3445

3546
let projects = match get_projects(env, access_token).await {
3647
Ok(x) => x,
37-
Err(_) => return Err(ConfigError::InputError),
48+
Err(_) => {
49+
return Err(ErrorResponse::Error {
50+
error_code: ErrorCode::InputError,
51+
message: ErrorCode::InputError.message(None).to_string(),
52+
})
53+
}
3854
};
3955

4056
let project: Project = if !projects.is_empty() {
@@ -56,12 +72,21 @@ pub async fn setup_project(env: Environment) -> Result<Config, ConfigError> {
5672
// Ensure .smb directory exists
5773
let smb_dir = Path::new(".smb");
5874
if !smb_dir.exists() {
59-
fs::create_dir(smb_dir).map_err(|_| ConfigError::MissingConfig)?;
75+
fs::create_dir(smb_dir).map_err(|_| ErrorResponse::Error {
76+
error_code: ErrorCode::MissingConfig,
77+
message: ErrorCode::MissingConfig.message(None).to_string(),
78+
})?;
6079
}
6180

6281
// Write config to .smb/config.toml
63-
let config_toml = toml::to_string(&config).map_err(|_| ConfigError::MissingConfig)?;
64-
fs::write(".smb/config.toml", config_toml).map_err(|_| ConfigError::MissingConfig)?;
82+
let config_toml = toml::to_string(&config).map_err(|_| ErrorResponse::Error {
83+
error_code: ErrorCode::MissingConfig,
84+
message: ErrorCode::MissingConfig.message(None).to_string(),
85+
})?;
86+
fs::write(".smb/config.toml", config_toml).map_err(|_| ErrorResponse::Error {
87+
error_code: ErrorCode::MissingConfig,
88+
message: ErrorCode::MissingConfig.message(None).to_string(),
89+
})?;
6590

6691
Ok(config)
6792
}
@@ -70,11 +95,14 @@ async fn select_project(
7095
env: Environment,
7196
projects: Vec<Project>,
7297
path: &str,
73-
) -> Result<Project, ConfigError> {
98+
) -> Result<Project, ErrorResponse> {
7499
let confirm = Confirm::with_theme(&ColorfulTheme::default())
75100
.with_prompt("Use existing project? y/n")
76101
.interact()
77-
.map_err(|_| ConfigError::InputError)?;
102+
.map_err(|_| ErrorResponse::Error {
103+
error_code: ErrorCode::InputError,
104+
message: ErrorCode::InputError.message(None).to_string(),
105+
})?;
78106

79107
if !confirm {
80108
return create_new_project(env, path).await;
@@ -83,18 +111,24 @@ async fn select_project(
83111
.items(&projects)
84112
.default(0)
85113
.interact()
86-
.map_err(|_| ConfigError::InputError)?;
114+
.map_err(|_| ErrorResponse::Error {
115+
error_code: ErrorCode::InputError,
116+
message: ErrorCode::InputError.message(None).to_string(),
117+
})?;
87118

88119
let project = projects[selection].clone();
89120

90121
Ok(project)
91122
}
92123

93-
async fn create_new_project(env: Environment, path: &str) -> Result<Project, ConfigError> {
124+
async fn create_new_project(env: Environment, path: &str) -> Result<Project, ErrorResponse> {
94125
let default_name = Path::new(path)
95126
.file_name()
96127
.and_then(|os_str| os_str.to_str())
97-
.unwrap_or("project");
128+
.unwrap_or("project")
129+
.to_lowercase()
130+
.replace([' ', '-'], "")
131+
.replace('-', "");
98132

99133
let name = match Input::<String>::with_theme(&ColorfulTheme::default())
100134
.with_prompt("Project name")
@@ -103,7 +137,10 @@ async fn create_new_project(env: Environment, path: &str) -> Result<Project, Con
103137
{
104138
Ok(project_name) => project_name,
105139
Err(_) => {
106-
return Err(ConfigError::InputError);
140+
return Err(ErrorResponse::Error {
141+
error_code: ErrorCode::InputError,
142+
message: ErrorCode::InputError.message(None).to_string(),
143+
});
107144
}
108145
};
109146

@@ -123,7 +160,10 @@ async fn create_new_project(env: Environment, path: &str) -> Result<Project, Con
123160
{
124161
Ok(repo) => repo,
125162
Err(_) => {
126-
return Err(ConfigError::InputError);
163+
return Err(ErrorResponse::Error {
164+
error_code: ErrorCode::InputError,
165+
message: ErrorCode::InputError.message(None).to_string(),
166+
});
127167
}
128168
};
129169

@@ -133,13 +173,21 @@ async fn create_new_project(env: Environment, path: &str) -> Result<Project, Con
133173
{
134174
Ok(description) => description,
135175
Err(_) => {
136-
return Err(ConfigError::InputError);
176+
return Err(ErrorResponse::Error {
177+
error_code: ErrorCode::InputError,
178+
message: ErrorCode::InputError.message(None).to_string(),
179+
});
137180
}
138181
};
139182

140183
let access_token = match get_smb_token(env).await {
141184
Ok(token) => token,
142-
Err(_) => return Err(ConfigError::MissingToken),
185+
Err(_) => {
186+
return Err(ErrorResponse::Error {
187+
error_code: ErrorCode::Unauthorized,
188+
message: ErrorCode::Unauthorized.message(None).to_string(),
189+
})
190+
}
143191
};
144192

145193
match create_project(
@@ -154,6 +202,6 @@ async fn create_new_project(env: Environment, path: &str) -> Result<Project, Con
154202
.await
155203
{
156204
Ok(project) => Ok(project),
157-
Err(_) => Err(ConfigError::MissingConfig),
205+
Err(e) => Err(e),
158206
}
159207
}

crates/cli/src/project/crud_create.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ pub async fn process_project_init(env: Environment) -> Result<CommandResult> {
2727
}
2828
};
2929
let repository = match Input::<String>::with_theme(&ColorfulTheme::default())
30-
.with_prompt("Project name")
30+
.with_prompt("Repository name")
3131
.interact()
3232
{
3333
Ok(project_name) => project_name,
3434
Err(_) => {
35-
return Err(anyhow!(fail_message("Invalid project name.")));
35+
return Err(anyhow!(fail_message("Invalid repository name.")));
3636
}
3737
};
3838
let description = match Input::<String>::with_theme(&ColorfulTheme::default())
@@ -91,6 +91,7 @@ description = "{description}"
9191
[project]
9292
id = 1
9393
name = "{repository_name}"
94+
repository = "{repository_name}"
9495
description = "{description}"
9596
created_at = "{now}"
9697
updated_at = "{now}"

crates/smbcloud-model/src/error_codes.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,21 @@ impl Display for ErrorResponse {
2424
#[derive(Error, Serialize_repr, Deserialize_repr, Debug, EnumIter, IntoStaticStr)]
2525
#[repr(i32)]
2626
pub enum ErrorCode {
27+
// Generic errors
2728
#[error("Unknown error.")]
2829
Unknown = 0,
2930
#[error("Parse error.")]
3031
ParseError = 1,
3132
#[error("Network error.")]
3233
NetworkError = 2,
34+
#[error("Input error")]
35+
InputError = 3,
36+
#[error("Missing config file. Please regenerate with 'smb init'.")]
37+
MissingConfig = 4,
38+
// #[error("Missing id in repository. Please regenerate with 'smb init'.")]
39+
// MissingId,
40+
#[error("Cancel operation.")]
41+
Cancel = 5,
3342
// Account
3443
#[error("Unauthorized access.")]
3544
Unauthorized = 100,
@@ -47,9 +56,13 @@ impl ErrorCode {
4756
100 => ErrorCode::Unauthorized,
4857
// Projects
4958
1000 => ErrorCode::ProjectNotFound,
50-
// Fallback
59+
// Generic errors
60+
5 => ErrorCode::Cancel,
61+
4 => ErrorCode::MissingConfig,
62+
3 => ErrorCode::InputError,
5163
2 => ErrorCode::ParseError,
5264
1 => ErrorCode::NetworkError,
65+
// Fallback
5366
_ => ErrorCode::Unknown,
5467
}
5568
}
@@ -63,6 +76,9 @@ impl ErrorCode {
6376
ErrorCode::ParseError => "Parse error.",
6477
ErrorCode::NetworkError => "Network error.",
6578
ErrorCode::Unauthorized => "Unauthorized access.",
79+
ErrorCode::InputError => "Input error.",
80+
ErrorCode::MissingConfig => "Missing config.",
81+
ErrorCode::Cancel => "Cancelled operation.",
6682
}
6783
}
6884

docs/gems.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Publish gem
2+
3+
To publish the gem with native extension, there are multiple steps to do.
4+
5+
## Build the gem
6+
7+
- Make sure to publish the cli first since it will publish the `smbcloud-model` crate as well, which the gem depends on.
8+
- Update the Cargo dependency in `gems/model/ext/model/Cargo.toml`.
9+
- Build the gem: `bundle exec rake compile`.
10+
- Update the gem version in the `gem/model/lib/model/version.rb`. Just use the same version as the `smbcloud-model` crate.
11+
- Then publish the gem.

gems/model/Cargo.lock

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gems/model/ext/model/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ crate-type = ["cdylib"]
1212
magnus = { version = "0.7.1" }
1313
strum = "0.27"
1414
# Local crates
15-
smbcloud-model = "0.3"
15+
smbcloud-model = "0.3.17"
1616
#smbcloud-model = { path = "./../../../../crates/smbcloud-model"}

0 commit comments

Comments
 (0)