Skip to content

Commit bb81dbb

Browse files
authored
Merge pull request #321 from monadicus/fix-api-errors
fix(controlplane,cli): Add missing response bodies to many 404 errors, properly handle response bodies and errors on CLI
2 parents 9186c83 + 17b552d commit bb81dbb

File tree

20 files changed

+256
-147
lines changed

20 files changed

+256
-147
lines changed

.github/workflows/pr.yml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ on:
55
env:
66
CARGO_TERM_COLOR: always
77
RUST_BACKTRACE: 1
8-
# https://releases.rs/docs/1.82.0/ release date
9-
NIGHTLY_TOOLCHAIN: nightly-2024-10-17
8+
# https://releases.rs/docs/1.83.0/ release date
9+
NIGHTLY_TOOLCHAIN: nightly-2024-11-28
1010

1111
# Cancel in progress workflows on pull_requests.
1212
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
@@ -135,38 +135,38 @@ jobs:
135135
136136
- name: 🧪 Test All
137137
if: steps.changes.outputs.top_toml == 'true'
138-
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run --all --verbose --fail-fast --all-features --exclude snops-agent --exclude xtask
138+
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run --all --verbose --fail-fast --all-features --exclude snops-agent --exclude xtask --no-tests=warn
139139

140140
- name: 🧪 Test Aot
141141
if: steps.changes.outputs.aot == 'true' && steps.changes.outputs.top_toml == 'false'
142-
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snarkos-aot --verbose --fail-fast --all-features
142+
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snarkos-aot --verbose --fail-fast --all-features --no-tests=warn
143143

144144
- name: 🧪 Test Checkpoint
145145
# env:
146146
# RUSTFLAGS: -Zcodegen-backend=cranelift
147147
if: steps.changes.outputs.checkpoint == 'true' && steps.changes.outputs.top_toml == 'false'
148-
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snops-checkpoint --verbose --fail-fast --all-features
148+
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snops-checkpoint --verbose --fail-fast --all-features --no-tests=warn
149149

150150
- name: 🧪 Test Common
151151
# env:
152152
# RUSTFLAGS: -Zcodegen-backend=cranelift
153153
if: steps.changes.outputs.common == 'true' && steps.changes.outputs.top_toml == 'false'
154-
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snops-common --verbose --fail-fast --all-features
154+
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snops-common --verbose --fail-fast --all-features --no-tests=warn
155155

156156
- name: 🧪 Test Control Plane
157157
# env:
158158
# RUSTFLAGS: -Zcodegen-backend=cranelift
159159
if: (steps.changes.outputs.control_plane == 'true' || steps.changes.outputs.common == 'true') && steps.changes.outputs.top_toml == 'false'
160-
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snops --verbose --fail-fast --all-features
160+
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snops --verbose --fail-fast --all-features --no-tests=warn
161161

162162
- name: 🧪 Test Agent
163163
# env:
164164
# RUSTFLAGS: ""
165165
if: (steps.changes.outputs.agent == 'true' || steps.changes.outputs.common == 'true')
166-
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snops-agent --verbose --fail-fast --all-features
166+
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snops-agent --verbose --fail-fast --all-features --no-tests=warn
167167

168168
- name: 🧪 Test Scli
169169
# env:
170170
# RUSTFLAGS: -Zcodegen-backend=cranelift
171171
if: (steps.changes.outputs.scli == 'true' || steps.changes.outputs.common == 'true') && steps.changes.outputs.top_toml == 'false'
172-
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snops-cli --verbose --fail-fast --all-features
172+
run: cargo +${{ env.NIGHTLY_TOOLCHAIN }} nextest run -p snops-cli --verbose --fail-fast --all-features --no-tests=warn

crates/agent/src/reconcile/storage.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ pub struct LedgerReconciler<'a> {
205205
pub modify_handle: &'a mut Option<(AbortHandle, Arc<Mutex<Option<LedgerModifyResult>>>)>,
206206
}
207207

208-
impl<'a> LedgerReconciler<'a> {
208+
impl LedgerReconciler<'_> {
209209
pub fn untar_paths(&self) -> (PathBuf, &'static str) {
210210
if self.env_info.storage.persist {
211211
(

crates/agent/src/rpc/control.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl AgentService for AgentRpcServer {
177177
.state
178178
.get_env_info(env_id)
179179
.await
180-
.map_err(|_| AgentError::FailedToMakeRequest)?
180+
.map_err(|e| AgentError::FailedToGetEnvInfo(e.to_string()))?
181181
.network;
182182

183183
let url = format!(
@@ -186,26 +186,31 @@ impl AgentService for AgentRpcServer {
186186
self.state.cli.ports.rest
187187
);
188188
let response = reqwest::Client::new()
189-
.post(url)
189+
.post(&url)
190190
.header("Content-Type", "application/json")
191191
.body(tx)
192192
.send()
193193
.await
194-
.map_err(|_| AgentError::FailedToMakeRequest)?;
194+
.map_err(|e| AgentError::FailedToMakeRequest(format!("{url}: {e:?}")))?;
195195
let status = response.status();
196196
if status.is_success() {
197-
Ok(())
197+
return Ok(());
198198
// transaction already exists so this is technically a success
199-
} else if status.is_server_error()
200-
&& response
201-
.text()
202-
.await
203-
.ok()
199+
}
200+
201+
let text = response.text().await.ok();
202+
203+
if status.is_server_error()
204+
&& text
205+
.as_ref()
204206
.is_some_and(|text| text.contains("exists in the ledger"))
205207
{
206-
return Ok(());
208+
Ok(())
207209
} else {
208-
Err(AgentError::FailedToMakeRequest)
210+
Err(AgentError::FailedToMakeRequest(format!(
211+
"{url}: {status:?} {}",
212+
text.unwrap_or_else(|| "no error message".to_string())
213+
)))
209214
}
210215
}
211216

@@ -329,7 +334,7 @@ impl AgentService for AgentRpcServer {
329334
.ok_or(AgentError::NodeClientNotSet)?
330335
.get_block_lite(ctx, block_hash)
331336
.await
332-
.map_err(|_| AgentError::FailedToMakeRequest)?
337+
.map_err(|e| AgentError::FailedToMakeRequest(format!("block info: {e:?}")))?
333338
}
334339

335340
async fn find_transaction(
@@ -343,7 +348,7 @@ impl AgentService for AgentRpcServer {
343348
.ok_or(AgentError::NodeClientNotSet)?
344349
.find_transaction(context, tx_id)
345350
.await
346-
.map_err(|_| AgentError::FailedToMakeRequest)?
351+
.map_err(|e| AgentError::FailedToMakeRequest(format!("find tx: {e:?}")))?
347352
}
348353

349354
async fn get_status(self, ctx: Context) -> Result<AgentStatus, AgentError> {

crates/aot/src/accounts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub const BECH32M_CHARSET: &str = "0123456789acdefghjklmnpqrstuvwxyz";
3838
#[derive(Clone, Copy)]
3939
struct VanityCheck<'a>(&'a [bech32::u5]);
4040

41-
impl<'a> bech32::WriteBase32 for VanityCheck<'a> {
41+
impl bech32::WriteBase32 for VanityCheck<'_> {
4242
type Err = bool;
4343

4444
fn write_u5(&mut self, data: bech32::u5) -> std::result::Result<(), Self::Err> {

crates/aot/src/runner/rpc/node.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ impl<N: Network> NodeService for NodeRpcServer<N> {
6262

6363
block_db
6464
.find_block_hash(&tx_id)
65-
.map_err(|_| AgentError::FailedToMakeRequest)
65+
.map_err(|e| {
66+
AgentError::FailedToMakeRequest(format!("block hash for tx {tx_id}: {e:?}"))
67+
})
6668
.map(|hash| hash.map(|hash| hash.to_string()))
6769
}
6870

@@ -80,9 +82,9 @@ impl<N: Network> NodeService for NodeRpcServer<N> {
8082
.parse()
8183
.map_err(|_| AgentError::InvalidBlockHash)?;
8284

83-
let Some(height) = block_db
84-
.get_block_height(&hash)
85-
.map_err(|_| AgentError::FailedToMakeRequest)?
85+
let Some(height) = block_db.get_block_height(&hash).map_err(|e| {
86+
AgentError::FailedToMakeRequest(format!("block height for hash {hash}: {e:?}"))
87+
})?
8688
else {
8789
return Ok(None);
8890
};
@@ -91,9 +93,9 @@ impl<N: Network> NodeService for NodeRpcServer<N> {
9193
return Ok(None);
9294
};
9395

94-
let Some(transactions) = block_db
95-
.get_block_transactions(&hash)
96-
.map_err(|_| AgentError::FailedToMakeRequest)?
96+
let Some(transactions) = block_db.get_block_transactions(&hash).map_err(|e| {
97+
AgentError::FailedToMakeRequest(format!("transactions for height {height}: {e:?}"))
98+
})?
9799
else {
98100
return Ok(None);
99101
};

crates/cli/src/commands/env/action/mod.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use anyhow::Result;
44
use clap::Parser;
55
use clap_stdin::FileOrStdin;
66
use reqwest::{Client, RequestBuilder, Response};
7-
use serde_json::json;
7+
use serde_json::{json, Value};
88
use snops_cli::events::EventsClient;
99
use snops_common::{
1010
action_models::{AleoValue, WithTargets},
@@ -381,8 +381,24 @@ impl Action {
381381

382382
pub async fn post_and_wait_tx(url: &str, req: RequestBuilder) -> Result<()> {
383383
use snops_common::events::EventFilter::*;
384+
let res = req.send().await?;
384385

385-
let tx_id: String = req.send().await?.json().await?;
386+
if !res.status().is_success() {
387+
let value = match res.content_length() {
388+
Some(0) | None => {
389+
eprintln!("error {}", res.status());
390+
return Ok(());
391+
}
392+
_ => {
393+
let text = res.text().await?;
394+
serde_json::from_str(&text).unwrap_or_else(|_| Value::String(text))
395+
}
396+
};
397+
println!("{}", serde_json::to_string_pretty(&value)?);
398+
return Ok(());
399+
}
400+
401+
let tx_id: String = res.json().await?;
386402
eprintln!("transaction id: {tx_id}");
387403

388404
let mut events = EventsClient::open_with_filter(url, TransactionIs(Arc::new(tx_id))).await?;

crates/cli/src/commands/env/mod.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use anyhow::Result;
55
use clap::{Parser, ValueHint};
66
use clap_stdin::FileOrStdin;
77
use reqwest::{Client, RequestBuilder, Response};
8+
use serde_json::Value;
89
use snops_cli::events::EventsClient;
910
use snops_common::{
1011
action_models::AleoValue,
@@ -287,11 +288,18 @@ pub async fn post_and_wait(url: &str, req: RequestBuilder, env_id: EnvId) -> Res
287288
let res = req.send().await?;
288289

289290
if !res.status().is_success() {
290-
println!(
291-
"{}",
292-
serde_json::to_string_pretty(&res.json::<serde_json::Value>().await?)?
293-
);
294-
std::process::exit(1);
291+
let value = match res.content_length() {
292+
Some(0) | None => {
293+
eprintln!("error: {}", res.status());
294+
return Ok(());
295+
}
296+
_ => {
297+
let text = res.text().await?;
298+
serde_json::from_str(&text).unwrap_or_else(|_| Value::String(text))
299+
}
300+
};
301+
println!("{}", serde_json::to_string_pretty(&value)?);
302+
return Ok(());
295303
}
296304

297305
let mut node_map: HashMap<NodeKey, AgentId> = res.json().await?;

crates/cli/src/commands/mod.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,19 @@ impl Commands {
8484
}
8585
}?;
8686

87-
if !response.status().is_success() {
88-
eprintln!("error {}", response.status());
89-
}
90-
9187
let value = match response.content_length() {
92-
Some(0) | None => None,
93-
_ => response.json::<Value>().await.map(Some)?,
88+
Some(0) | None => {
89+
if !response.status().is_success() {
90+
eprintln!("error {}", response.status());
91+
} else {
92+
eprintln!("{}", response.status());
93+
}
94+
return Ok(());
95+
}
96+
_ => {
97+
let text = response.text().await?;
98+
serde_json::from_str(&text).unwrap_or_else(|_| Value::String(text))
99+
}
94100
};
95101

96102
println!("{}", serde_json::to_string_pretty(&value)?);

crates/common/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ clap.workspace = true
1919
clap_mangen = { workspace = true, optional = true }
2020
clap-markdown = { workspace = true, optional = true }
2121
futures.workspace = true
22-
http.workspace = true
22+
http = { workspace = true, features = ["std"] }
2323
indexmap = { workspace = true, features = ["std", "serde"] }
2424
lasso.workspace = true
2525
lazy_static.workspace = true
@@ -36,7 +36,7 @@ tarpc.workspace = true
3636
thiserror.workspace = true
3737
tokio = { workspace = true, features = ["process"] }
3838
tracing.workspace = true
39-
url.workspace = true
39+
url = { workspace = true, features = ["serde"] }
4040
wildmatch.workspace = true
4141

4242
[dev-dependencies]

crates/common/src/action_models.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
66
use crate::{
77
key_source::KeySource,
88
node_targets::{NodeTarget, NodeTargets},
9-
state::{CannonId, HeightRequest, InternedId},
9+
state::HeightRequest,
1010
};
1111

1212
#[derive(Deserialize, Serialize, Clone)]
@@ -41,6 +41,10 @@ fn credits_aleo() -> String {
4141
"credits.aleo".to_owned()
4242
}
4343

44+
fn default_str() -> String {
45+
"default".to_owned()
46+
}
47+
4448
#[derive(Debug, Clone, Serialize, Deserialize)]
4549
#[serde(rename_all = "snake_case")]
4650
pub struct ExecuteAction {
@@ -57,8 +61,8 @@ pub struct ExecuteAction {
5761
/// The function to call
5862
pub function: String,
5963
/// The cannon id of who to execute the transaction
60-
#[serde(default)]
61-
pub cannon: CannonId,
64+
#[serde(default = "default_str")]
65+
pub cannon: String,
6266
/// The inputs to the function
6367
pub inputs: Vec<AleoValue>,
6468
/// The optional priority fee
@@ -82,8 +86,8 @@ pub struct DeployAction {
8286
/// The program to deploy
8387
pub program: String,
8488
/// The cannon id of who to execute the transaction
85-
#[serde(default)]
86-
pub cannon: CannonId,
89+
#[serde(default = "default_str")]
90+
pub cannon: String,
8791
/// The optional priority fee
8892
#[serde(default)]
8993
pub priority_fee: Option<u64>,
@@ -122,7 +126,7 @@ pub struct Reconfig {
122126
#[serde(default, skip_serializing_if = "Option::is_none")]
123127
pub validators: Option<NodeTargets>,
124128
#[serde(default, skip_serializing_if = "Option::is_none")]
125-
pub binary: Option<InternedId>,
129+
pub binary: Option<String>,
126130
#[serde(default, skip_serializing_if = "Option::is_none")]
127131
pub private_key: Option<KeySource>,
128132
#[serde(default, skip_serializing_if = "Option::is_none")]

0 commit comments

Comments
 (0)