Skip to content

Commit

Permalink
Merge pull request #284 from crepererum-oss/crepererum/debug_dump_json
Browse files Browse the repository at this point in the history
feat: add easy way to dump JSON data for debugging
  • Loading branch information
crepererum authored Sep 22, 2024
2 parents a43ec5c + 17facef commit caef1d4
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 5 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ tokio-retry = "0.3.0"
tracing = "0.1.38"
tracing-log = "0.2.0"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
uuid = { version = "1.10.0", features = ["v4"] }

[dev-dependencies]
assert_cmd = "2.0.16"
Expand Down
49 changes: 45 additions & 4 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{future::Future, sync::Arc};
use std::{future::Future, path::PathBuf, sync::Arc};

use anyhow::{Context, Result};
use futures::Stream;
Expand All @@ -9,6 +9,7 @@ use tokio::{
task::JoinSet,
};
use tracing::{debug, warn};
use uuid::Uuid;

use crate::{
constants::APP_USER_AGENT,
Expand All @@ -22,10 +23,11 @@ pub(crate) const DEFAULT_HOST: &str = "https://app.tuta.com";
#[derive(Debug, Clone)]
pub(crate) struct Client {
inner: reqwest::Client,
debug_dump_json_to: Option<PathBuf>,
}

impl Client {
pub(crate) fn try_new() -> Result<Self> {
pub(crate) async fn try_new(debug_dump_json_to: Option<PathBuf>) -> Result<Self> {
let inner = reqwest::Client::builder()
.hickory_dns(true)
.http2_adaptive_window(true)
Expand All @@ -36,7 +38,16 @@ impl Client {
.build()
.context("set up HTTPs client")?;

Ok(Self { inner })
if let Some(path) = &debug_dump_json_to {
tokio::fs::create_dir_all(path)
.await
.context("creating directories to dump JSON data")?;
}

Ok(Self {
inner,
debug_dump_json_to,
})
}

pub(crate) fn stream<Resp>(
Expand Down Expand Up @@ -121,10 +132,40 @@ impl Client {
{
let s = retry(|| async { self.do_request(r.clone()).await?.text().await }).await?;

let json_path = match &self.debug_dump_json_to {
Some(path) => {
let uuid = Uuid::new_v4();
let path = path.join(format!("{uuid}.json"));
debug!(%uuid, path=%path.display(), "dumping debug JSON");
tokio::fs::write(&path, &s)
.await
.context("dumping debug JSON")?;
Some(path)
}
None => None,
};

let jd = &mut serde_json::Deserializer::from_str(&s);
let res: Result<Resp, _> = serde_path_to_error::deserialize(jd);

res.with_context(|| format!("deserialize JSON for `{}`", std::any::type_name::<Resp>()))
res.with_context(|| {
let type_name = std::any::type_name::<Resp>();
match json_path {
Some(json_path) => {
format!(
"deserialize JSON for `{}`, data dumped to `{}`",
type_name,
json_path.display(),
)
}
None => {
format!(
"deserialize JSON for `{}`, consider passing `--debug-dump-json-to=some/path` to dump the data",
type_name,
)
}
}
})
}

pub(crate) async fn do_bytes<Req>(&self, r: Request<'_, Req>) -> Result<Vec<u8>>
Expand Down
10 changes: 9 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ struct Args {
#[clap(flatten)]
logging_cfg: LoggingCLIConfig,

/// Dump JSON responses of server to given folder.
///
/// This is useful for development and debugging.
#[clap(long)]
debug_dump_json_to: Option<PathBuf>,

/// Login config.
#[clap(flatten)]
login_cfg: LoginCLIConfig,
Expand Down Expand Up @@ -85,7 +91,9 @@ async fn main() -> Result<()> {
let args = Args::parse();
setup_logging(args.logging_cfg).context("logging setup")?;

let client = Client::try_new().context("set up client")?;
let client = Client::try_new(args.debug_dump_json_to)
.await
.context("set up client")?;

let session = Session::login(args.login_cfg, &client)
.await
Expand Down
18 changes: 18 additions & 0 deletions tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@ fn read_files(path: &Path) -> HashMap<String, String> {
mod integration {
use super::*;

#[test]
fn test_debug_dump_json() {
let tmp_dir = TempDir::new().unwrap();

// use path that does NOT exist
let dump_dir = tmp_dir.path().join("json");

let mut cmd = cmd();
cmd.arg("-vv")
.arg("--debug-dump-json-to")
.arg(&dump_dir)
.arg("list-folders")
.assert()
.success();

assert!(std::fs::read_dir(dump_dir).unwrap().count() > 0);
}

#[test]
fn test_list_folders() {
let mut cmd = cmd();
Expand Down

0 comments on commit caef1d4

Please sign in to comment.