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

Properly handle final path errors #92

Merged
merged 3 commits into from
Aug 24, 2023

Conversation

orhun
Copy link
Contributor

@orhun orhun commented Aug 21, 2023

Fixes #91

The thing is, when the question mark is operator is used, the error is returned to main:

tere/src/main.rs

Lines 69 to 72 in 8a97cd4

let final_path = TereAppState::init(settings, &warnings)
.and_then(|state| TereTui::init(state, &mut stderr))
// actually run the app and return the final path
.and_then(|mut ui| ui.main_event_loop())?;

Thus the next error handling part is never executed:

tere/src/main.rs

Lines 80 to 96 in 8a97cd4

let (final_path, warnings) = match res {
Err(err) => {
match err {
// Print pretty error message if the error was in arg parsing
TereError::Clap(e) => e.exit(),
TereError::ExitWithoutCd(msg) | TereError::FirstRunPromptCancelled(msg) => {
eprintln!("{msg}");
std::process::exit(1);
}
// exit in case of any other error
e => return Err(e),
}
}
Ok(path) => path,
};

This PR removes the question mark operator and uses the good old match arms to return the error to the actual scope.

@mgunyho
Copy link
Owner

mgunyho commented Aug 21, 2023

Ah, good catch! I think I somehow thought that the question mark would only go up to the enclosing block, but it goes all the way up because the block is not a function.

This same can be achieved with another and_then: instead if final_path = ..., we can just have

                TereAppState::init(settings, &warnings)
                    .and_then(|state| TereTui::init(state, &mut stderr))
                    // actually run the app and return the final path
                    .and_then(|mut ui| ui.main_event_loop())
                    .and_then(|final_path| Ok((final_path, warnings)))

(note no semicolon at the end)

I think we should also check the first question mark (at the end of chain producing (settings, warnings)), whether it should bubble all the way up, I'll think about it a bit later today or tomorrow.

Edit: oh, clippy tells me that it can be just

.map(|final_path| (final_path, warnings))

@mgunyho
Copy link
Owner

mgunyho commented Aug 21, 2023

Yeah for example if I delete (or rename) the history json file so I get the first run prompt, cancelling it prints

Error: FirstRunPromptCancelled("Cancelled.")

even though it should be just Cancelled.. So I don't think we want the first question mark to bubble up either.

The full execution could be just chained together into a big sequence:

                stderr
                    .flush()
                    .map_err(TereError::from)
                    .and_then(|_| TereSettings::parse_cli_args(&cli_args))
                    .and_then(|(settings, warnings)| {
                        check_first_run_with_prompt(&settings, &mut stderr)?;
                        Ok((settings, warnings))
                    })
                    .and_then(|(settings, warnings)| {
                        TereAppState::init(settings, &warnings)
                            .and_then(|state| TereTui::init(state, &mut stderr))
                            // actually run the app and return the final path
                            .and_then(|mut ui| ui.main_event_loop())
                            .map(|final_path| (final_path, warnings))
                    })

I'm not sure why I didn't do it this way originally, maybe this is a bit harder to follow.

@orhun
Copy link
Contributor Author

orhun commented Aug 23, 2023

Sorry for the late reply.

That makes a lot of sense. Made the change in b9e06ef

@mgunyho
Copy link
Owner

mgunyho commented Aug 23, 2023

No worries, thanks! I'm currently down a rabbit hole of pseudo-terminals and terminal escape code handling, trying to write an integration test that would check the stdout/stderr.

@orhun
Copy link
Contributor Author

orhun commented Aug 23, 2023

Definitely sounds interesting, let me know if you need any changes in the PR anytime soon!

@mgunyho
Copy link
Owner

mgunyho commented Aug 24, 2023

Okay I've added (failing) tests for the output of the whole app in 70d2686. I'll rebase this on top of it to check that the tests pass and then merge.

@mgunyho mgunyho changed the base branch from master to develop August 24, 2023 18:26
@mgunyho mgunyho merged commit 45a4b18 into mgunyho:develop Aug 24, 2023
mgunyho added a commit that referenced this pull request Aug 24, 2023
- Fix output formatting when exiting the app without cd, or when canceling the first run prompt (Thanks @orhun, Github #91, #92)
- Update dependencies
- Improved tests
@mgunyho
Copy link
Owner

mgunyho commented Aug 24, 2023

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Error message formatting when exiting without cd
2 participants