Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/improve exec error message #71

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

AngeCyp
Copy link
Contributor

@AngeCyp AngeCyp commented Nov 27, 2024

Fix #6

This PR add a better message when using the exec mode and if the executable is not found.

app-agent/src/exec_process.rs Show resolved Hide resolved
app-agent/src/exec_process.rs Outdated Show resolved Hide resolved
Err(e) => match e.kind() {
std::io::ErrorKind::NotFound => {
let directory_entries_iter = fs::read_dir("./").unwrap();
let mut entry_list = String::from("Available files in the current directory:\n");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's up to the agent to replace ls.
How about just doing these two things:

If ErrorKind::NotFound

  • check if a file with the same name exists in the current directory
  • print:
command 'XYZ' not found
Hint: A file named 'XYZ' exists in the current directory. Prepend ./ to execute it.
Example: CMD exec './XYZ'

where CMD is the alumet binary (in the rapl plugin you can find an example of how to get the path to the current alumet binary on the user).

Bonus

If you want to have fun, implement a fuzzy finder to fix the potential typos :)
Example of what it would look like:

> ls
script.sh

> alumet-local-agent exec ./scrit.sh
ERROR: ...
Hint: did you mean './script.sh'?

Other example:

> ls
script.sh

> alumet-local-agent exec ./script
ERROR: ...
Hint: did you mean './script.sh'?

If permission denied

  • check if the file exists but does not have the X or R permission
  • print:
file 'XYZ' is missing the following permissions: PERM
Hint: try chmod +PERM 'XYZ'

where PERM is r, x or rx

@TheElectronWill TheElectronWill added the A:app-agent area: runnable agent application label Nov 28, 2024
@AngeCyp AngeCyp force-pushed the feature/improve-exec-error-message branch from 3e8c5f6 to eeb5269 Compare November 29, 2024 12:20
Copy link
Contributor

@TheElectronWill TheElectronWill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When done, it will be a nice improvement to the agent exec mode!

.cspell/project-words.txt Show resolved Hide resolved
Comment on lines 31 to 42
Err(e) => match e.kind() {
std::io::ErrorKind::NotFound => {
let return_error: String = handle_not_found(external_command, args);
panic!("{}", return_error);
}
std::io::ErrorKind::PermissionDenied => {
let return_error: String = handle_permission_denied(external_command);
panic!("{}", return_error);
}
_ => {
panic!("Error in child process");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function returns a Result, you should use that instead of panics.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As in the main you used expect() I expected to panic in case of error

let file_permission_denied = match File::open(external_command.clone()) {
Ok(file) => file,
Err(err) => {
panic!("Error when try to read the file: {}", err);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

english

4 => "x",
_ => "",
};
if user_perm == "rx" || group_perm == "rx" || other_perm == "rx" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is all this doing, exactly? Isn't chmod +rx a solution that always work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I check which rights are missing, the goal is to suggest only to add missing rights, if read is missing but not execute, i will suggest chmod +r only

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's very generous of your part, but chmod does the checking, no? If chmod +r works, chmod +rx will work too. Something that would really be helpful is, maybe, to check the permissions of the folder: what happens if the user wants to execute /a/b/exec but /a/b is not readable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, if +r is missing, +rx will work too. I found it was more interesting for people to see that, for example, if only read right is missing, but the execute one is already present... But it's as you want, I can just suggest one chmod: chmod +rx.
About the parent folder, you're totally right, I will check this right in my next commit. I will only check the parent folder but not the parent of the parents, as it could be veryyyyyy long and not necessary, in my opinion

Copy link
Contributor Author

@AngeCyp AngeCyp Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding to 3788bde I check parent of parent to be sure all folder in the path have at least the 'execute' right

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to do that, do it properly: compute the missing permissions and print the message that suggests it in one go, without repeating all the possibilities (lines 148 to 162 should be just 2 lines).

app-agent/src/exec_process.rs Outdated Show resolved Hide resolved
app-agent/src/utils.rs Outdated Show resolved Hide resolved
app-agent/src/utils.rs Outdated Show resolved Hide resolved
@AngeCyp AngeCyp force-pushed the feature/improve-exec-error-message branch from 833e56b to 3788bde Compare December 11, 2024 16:46
@AngeCyp AngeCyp force-pushed the feature/improve-exec-error-message branch from 3788bde to 69a75cf Compare January 6, 2025 08:31
@AngeCyp AngeCyp force-pushed the feature/improve-exec-error-message branch from 69a75cf to 264ef6f Compare January 7, 2025 10:06
return Err(anyhow!(return_error));
}
_ => {
panic!("Error in child process");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exec_child returns a result, please remove the panics

Comment on lines 58 to 60
let file_permission_denied = match File::open(external_command.clone()) {
Ok(file) => file,
Err(err) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the Ok branch is very small, you can turn this into a if let instead. Also, what does file_permission_denied represent?

It would be cleaner to make it a separate function.

Comment on lines 68 to 84
let metadata: Metadata;
loop {
match current_parent.metadata() {
Ok(metadata_parent) => {
metadata = metadata_parent;
break;
}
Err(_) => {
current_parent = match current_parent.parent() {
Some(parent) => parent,
None => {
panic!("Unable to retrieve a parent for your file");
}
}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be cleaner to make it a separate function

Comment on lines 128 to 133
let user_perm = match file_metadata.permissions().mode() & 0o500 {
0 => "rx",
1 => "r",
4 => "x",
_ => "",
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A function would be handy for deduplication here.

4 => "x",
_ => "",
};
if user_perm == "rx" || group_perm == "rx" || other_perm == "rx" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to do that, do it properly: compute the missing permissions and print the message that suggests it in one go, without repeating all the possibilities (lines 148 to 162 should be just 2 lines).

} else {
log::warn!("Can't determine right issue about the file: {}", external_command);
}
"Issue happened about file's permission".to_string()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which issue? Use proper errors propagation

Comment on lines 214 to 223
args.iter()
.map(|arg| {
if arg.contains(' ') {
format!("\"{}\"", arg)
} else {
arg.to_string()
}
})
.collect::<Vec<_>>()
.join(" ")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please separate the construction of the list from the log call (same everywhere).

}
}
None => {
log::warn!("💡 Hint: No matching file exists in the current directory. Prepend ./ to execute it.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What? If there's no matching file, prepending ./ will never work.

log::warn!("💡 Hint: No matching file exists in the current directory. Prepend ./ to execute it.");
}
}
"Issue happened because the file was not found".to_string()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which issue?

@@ -6,6 +6,7 @@ pub mod agent_util;
pub mod config_ops;
pub mod exec_process;
pub mod options;
pub mod utils;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please find a better name than utils. I suggest word_distance

@@ -0,0 +1,170 @@
use std::collections::HashMap;

// Damerau-Levenshtein distance
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use triple slash to document function. Please add more details so that we understand what this is without googling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A:app-agent area: runnable agent application
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve error message for exec mode
2 participants