-
Notifications
You must be signed in to change notification settings - Fork 39
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
Propagate error if the fs read for ohttp keys fails during config #435
base: master
Are you sure you want to change the base?
Conversation
ae95d17
to
35511cd
Compare
Pull Request Test Coverage Report for Build 12241238964Details
💛 - Coveralls |
35511cd
to
b845813
Compare
How did you test this? I manually sent a GET request to payjo.in/ohttp-keys, placed the response pj_directory="https://payjo.in"
ohttp_relay="https://pj.bobspacebkk.com"
ohttp_keys="<payjoin-cli working directory from which the program is called>/ohttp-keys" and ran Error: Failed to parse config
Caused by:
invalid type: string "/Users/dan/f/dev/payjoin/payjoin-cli/ohttp-keys", expected a sequence Perhaps OR perhaps my input to the config.toml isn't parsed as a path to be passed to std::file::read |
@DanGould ah i wrongly assumed that since some of the tests failed when i incorrectly implemented this, that when they passed, it would mean this part is tested. Let me take a deeper look into this and get it tested. I'll update here once i figure it out |
@DanGould I used the
I'm gonna mess around with it a bit - there's definitely something wrong with my implementation here |
Ok, I think I've figured it out. It looks like the error actually IS getting propagated already. I tested this by calling:
which resulted in:
so it looks like the error is being propagated since i can see this bit: However, there's an issue when the CLI argument pub(crate) fn new(matches: &ArgMatches) -> Result<Self, ConfigError> {
let builder = Config::builder()
.set_default("bitcoind_rpchost", "http://localhost:18443")?
...
.add_source(File::new("config.toml", FileFormat::Toml).required(false)); // <--- here This is a problem because the current code that parses the CLI: From the
So, the issue isn't one of error propagation, but how to use the value in the config file as the file path for the ohttp keys. It looks like setting the value after the |
Kudos for keeping after it and seeing this investigation through. Super proud for you to have chosen to bless rust-payjoin with these contributions 🏎️
(Default directory for configuration and persistent data is related to #64.) The original intent with this design was for Since the overarching theme is to pay back tech debt, it might make more sense to start with the |
It's late here so I'm reading this while i'm kinda sleepy but that makes sense for the most part. I just ran this command against the changes in this branch and what's currently in master:
The
The error wasn't propagated, and it continues to run until it tries building the Config from In the run with these PR changes, the output is now:
so the error is propagated and the user will now know that the read failed instead of getting a somewhat unrelated error of a different path not being a sequence |
Sorry for the long discussion for this task. For some reason I couldn't initially figure out the ArgMatches stuff and i couldn't let it go so i focused on that rather than the actual goal of the PR 😅 |
I see and was able to test as you have to success when using the cli argument, however, I get the "expected a sequence" error when setting #[serde(deserialize_with = "deserialize_ohttp_keys_from_path")]
pub ohttp_keys: Option<payjoin::OhttpKeys>, #[cfg(feature = "v2")]
let ohttp_keys = matches.get_one::<String>("ohttp_keys").map(|s| s.as_str()); (it might make sense to combine the above and below lines as is done in other parts of the config) .set_override_option("ohttp_keys", ohttp_keys)? #[cfg(feature = "v2")]
fn deserialize_ohttp_keys_from_path<'de, D>(
deserializer: D,
) -> Result<Option<payjoin::OhttpKeys>, D::Error>
where
D: serde::Deserializer<'de>,
{
let path_str: Option<String> = Option::deserialize(deserializer)?;
match path_str {
None => Ok(None),
Some(path) => std::fs::read(path)
.map_err(|e| serde::de::Error::custom(format!("Failed to read ohttp_keys file: {}", e)))
.and_then(|bytes| {
payjoin::OhttpKeys::decode(&bytes).map_err(|e| {
serde::de::Error::custom(format!("Failed to decode ohttp keys: {}", e))
})
})
.map(Some),
}
} |
Sometimes it just takes a discussion to hash things out. Best to put the conclusion of this discussion in a commit message so that the next person who comes to find it understands what the heck we were talking about 😄 |
Nice, I like the custom deserializer solution! Two birds with one stone. I'll update here in a bit |
Having some trouble with the test in payjoin-cli/tests/e2e.rs after adding the deserializer:
Since |
If you can push the version you think is broken I can check it within 12 hours |
Fixes #398