Skip to content

Commit c69fe8e

Browse files
Web3NLclaude
andcommitted
fix: make MCD and MCF logs user-friendly (#117)
- Add Display impl for TopUpInterval (outputs "hourly", "daily", etc. instead of raw Rust debug format) - Add Display impl for NotifyError with readable messages - Replace {e:?} debug formatting with {e} Display formatting in all error strings (both crates) - Fix inconsistent log prefixes ("Mint in-flight" and "CMC mint error" now use "top-up:" prefix like all other messages) Closes #117 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5acdf56 commit c69fe8e

2 files changed

Lines changed: 47 additions & 13 deletions

File tree

packages-rs/my-canister-dashboard/src/dashboard/top_up_rule.rs

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ pub fn manage_top_up_rule(arg: ManageTopUpRuleArg) -> ManageTopUpRuleResult {
157157
*cell.borrow_mut() = Some(rule.clone());
158158
});
159159
ic_cdk::println!(
160-
"top-up: rule set amount={} threshold={} interval={:?}",
160+
"top-up: rule set amount={} threshold={} interval={}",
161161
rule.cycles_amount.as_cycles(),
162162
rule.cycles_threshold.as_cycles(),
163163
rule.interval
@@ -202,7 +202,7 @@ async fn on_top_up_interval_tick() {
202202
if let Some(rule) = current_rule() {
203203
let every = interval_duration(&rule.interval).as_secs();
204204
ic_cdk::println!(
205-
"top-up: active rule amount={} threshold={} interval={:?} every={}s",
205+
"top-up: active rule amount={} threshold={} interval={} every={}s",
206206
rule.cycles_amount.as_cycles(),
207207
rule.cycles_threshold.as_cycles(),
208208
rule.interval,
@@ -229,13 +229,13 @@ async fn on_top_up_interval_tick() {
229229
// Skip if previous mint is still in flight
230230
let busy = TOP_UP_MINT_INFLIGHT.with(|f| *f.borrow());
231231
if busy {
232-
ic_cdk::println!("Mint in-flight; skipping this tick");
232+
ic_cdk::println!("top-up: mint in-flight, skipping this tick");
233233
} else {
234234
TOP_UP_MINT_INFLIGHT.with(|f| *f.borrow_mut() = true);
235235
ic_cdk::println!("top-up: starting transfer + notify flow");
236236
let res = cmc_deposit_and_mint(needed_icp_e8s).await;
237237
if let Err(e) = res {
238-
ic_cdk::println!("CMC mint error: {}", e);
238+
ic_cdk::println!("top-up: CMC mint error: {}", e);
239239
} else {
240240
ic_cdk::println!("top-up: flow completed");
241241
}
@@ -262,6 +262,17 @@ async fn on_top_up_interval_tick() {
262262
}
263263
}
264264

265+
impl std::fmt::Display for TopUpInterval {
266+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
267+
match self {
268+
TopUpInterval::Hourly => write!(f, "hourly"),
269+
TopUpInterval::Daily => write!(f, "daily"),
270+
TopUpInterval::Weekly => write!(f, "weekly"),
271+
TopUpInterval::Monthly => write!(f, "monthly"),
272+
}
273+
}
274+
}
275+
265276
fn interval_duration(interval: &TopUpInterval) -> std::time::Duration {
266277
use std::time::Duration;
267278
match interval {
@@ -319,10 +330,10 @@ async fn fetch_cycles_per_icp() -> Result<u64, String> {
319330
let res = Call::unbounded_wait(cmc, "get_icp_xdr_conversion_rate")
320331
.with_arg(())
321332
.await
322-
.map_err(|e| format!("get_icp_xdr_conversion_rate failed: {e:?}"))?;
333+
.map_err(|e| format!("get_icp_xdr_conversion_rate failed: {e}"))?;
323334
let resp: IcpXdrConversionRateResponse = res
324335
.candid()
325-
.map_err(|e| format!("get_icp_xdr_conversion_rate candid decode failed: {e:?}"))?;
336+
.map_err(|e| format!("get_icp_xdr_conversion_rate candid decode failed: {e}"))?;
326337

327338
let permyriad = resp.data.xdr_permyriad_per_icp as u128; // XDR*10_000 per 1 ICP
328339
// cycles_per_icp = (permyriad / 10_000) * 1e12 = permyriad * 1e8
@@ -394,7 +405,7 @@ async fn cmc_deposit_and_mint(amount_e8s: u64) -> Result<(), String> {
394405
Err(e) => {
395406
// Drop stored index on non-retriable errors
396407
TOP_UP_LAST_BLOCK_INDEX.with(|c| *c.borrow_mut() = None);
397-
Err(format!("CMC notify_top_up error: {e:?}"))
408+
Err(format!("CMC notify_top_up error: {e}"))
398409
}
399410
}
400411
}
@@ -436,13 +447,13 @@ async fn ledger_transfer_to_cmc_topup(
436447
let res = Call::unbounded_wait(ledger, "transfer")
437448
.with_arg(arg)
438449
.await
439-
.map_err(|e| format!("transfer failed: {e:?}"))?;
450+
.map_err(|e| format!("transfer failed: {e}"))?;
440451

441452
let result: Result<BlockIndex, TransferError> = res
442453
.candid()
443-
.map_err(|e| format!("transfer candid decode failed: {e:?}"))?;
454+
.map_err(|e| format!("transfer candid decode failed: {e}"))?;
444455

445-
result.map_err(|e| format!("transfer error: {e:?}"))
456+
result.map_err(|e| format!("transfer error: {e}"))
446457
}
447458

448459
// notify_top_up definitions and call
@@ -467,6 +478,29 @@ enum NotifyError {
467478
},
468479
}
469480

481+
impl std::fmt::Display for NotifyError {
482+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
483+
match self {
484+
NotifyError::Refunded {
485+
reason,
486+
block_index,
487+
} => match block_index {
488+
Some(idx) => write!(f, "refunded: {reason} (block_index={idx})"),
489+
None => write!(f, "refunded: {reason}"),
490+
},
491+
NotifyError::Processing => write!(f, "processing"),
492+
NotifyError::TransactionTooOld(block) => {
493+
write!(f, "transaction too old (block_index={block})")
494+
}
495+
NotifyError::InvalidTransaction(msg) => write!(f, "invalid transaction: {msg}"),
496+
NotifyError::Other {
497+
error_code,
498+
error_message,
499+
} => write!(f, "{error_message} (code={error_code})"),
500+
}
501+
}
502+
}
503+
470504
#[derive(CandidType, Deserialize, Debug)]
471505
enum NotifyTopUpResult {
472506
Ok(Nat),
@@ -487,11 +521,11 @@ async fn cmc_notify_top_up(block_index: u64, canister_id: Principal) -> Result<N
487521
.await
488522
.map_err(|e| NotifyError::Other {
489523
error_code: 1,
490-
error_message: format!("notify_top_up failed: {e:?}"),
524+
error_message: format!("notify_top_up failed: {e}"),
491525
})?;
492526
let result: NotifyTopUpResult = res.candid().map_err(|e| NotifyError::Other {
493527
error_code: 2,
494-
error_message: format!("notify_top_up candid decode failed: {e:?}"),
528+
error_message: format!("notify_top_up candid decode failed: {e}"),
495529
})?;
496530

497531
match result {

packages-rs/my-canister-frontend/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub fn setup_frontend_with_config(
6161
asset_router::with_asset_router_mut(|router| {
6262
router
6363
.certify_assets(assets, configs)
64-
.map_err(|e| format!("Failed to certify frontend assets: {e:?}"))?;
64+
.map_err(|e| format!("Failed to certify frontend assets: {e}"))?;
6565
certified_data_set(router.root_hash());
6666
Ok(())
6767
})

0 commit comments

Comments
 (0)