Skip to content

Commit c4fd813

Browse files
committed
Always add backtrace to cosmwasm-std
1 parent 8b3037c commit c4fd813

File tree

7 files changed

+122
-169
lines changed

7 files changed

+122
-169
lines changed

packages/std/Cargo.toml

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ iterator = []
2323
# CosmosMsg types, and new QueryRequest types. This should only be enabled on contracts
2424
# that require these types, so other contracts can be used on systems with eg. PoA consensus
2525
staking = []
26-
# backtraces provides much better context at runtime errors (in non-wasm code)
27-
# at the cost of a bit of code size and performance.
28-
# This feature requires Rust nightly because it depends on the unstable backtrace feature.
29-
backtraces = []
3026
# stargate enables stargate-dependent messages and queries, like raw protobuf messages
3127
# as well as ibc-related functionality
3228
stargate = []
@@ -54,10 +50,7 @@ forward_ref = "1"
5450
hex = "0.4"
5551
schemars = "0.8.3"
5652
sha2 = "0.10.3"
57-
serde = { version = "1.0.103", default-features = false, features = [
58-
"derive",
59-
"alloc",
60-
] }
53+
serde = { version = "1.0.103", default-features = false, features = ["derive", "alloc"] }
6154
serde-json-wasm = { version = "1.0.0" }
6255
thiserror = "1.0.26"
6356
bnum = "0.8.0"
@@ -70,10 +63,7 @@ cosmwasm-crypto = { path = "../crypto", version = "1.5.0" }
7063
[dev-dependencies]
7164
cosmwasm-schema = { path = "../schema" }
7265
# The chrono dependency is only used in an example, which Rust compiles for us. If this causes trouble, remove it.
73-
chrono = { version = "0.4", default-features = false, features = [
74-
"alloc",
75-
"std",
76-
] }
66+
chrono = { version = "0.4", default-features = false, features = ["alloc", "std"] }
7767
crc32fast = "1.3.2"
7868
hex-literal = "0.3.1"
7969
serde_json = "1.0.81"

packages/std/src/binary.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ mod tests {
335335
("cmFuZ", "Encoded text cannot have a 6-bit remainder."),
336336
] {
337337
match Binary::from_base64(invalid_base64) {
338-
Err(StdError::InvalidBase64 { msg }) => assert_eq!(want, msg),
338+
Err(StdError::InvalidBase64 { msg, .. }) => assert_eq!(want, msg),
339339
result => panic!("Unexpected result: {result:?}"),
340340
}
341341
}

packages/std/src/errors/backtrace.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use core::fmt::{Debug, Display, Formatter, Result};
2+
use thiserror::Error;
3+
4+
/// This wraps an actual backtrace to achieve two things:
5+
/// - being able to fill this with a stub implementation in `no_std` environments
6+
/// - being able to use this in conjunction with [`thiserror::Error`]
7+
#[derive(Error)]
8+
pub struct BT(Box<dyn Printable>);
9+
10+
impl BT {
11+
#[track_caller]
12+
pub fn capture() -> Self {
13+
BT(Box::new(std::backtrace::Backtrace::capture()))
14+
}
15+
}
16+
17+
trait Printable: Debug + Display {}
18+
impl<T> Printable for T where T: Debug + Display {}
19+
20+
impl Debug for BT {
21+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
22+
Debug::fmt(&self.0, f)
23+
}
24+
}
25+
26+
impl Display for BT {
27+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
28+
Display::fmt(&self.0, f)
29+
}
30+
}
31+
32+
/// This macro implements `From` for a given error type to a given error type where
33+
/// the target error has a `backtrace` field.
34+
/// This is meant as a replacement for `thiserror`'s `#[from]` attribute, which does not
35+
/// work with our custom backtrace wrapper.
36+
macro_rules! impl_from_err {
37+
($from:ty, $to:ty, $map:path) => {
38+
impl From<$from> for $to {
39+
fn from(err: $from) -> Self {
40+
$map {
41+
source: err,
42+
backtrace: $crate::errors::backtrace::BT::capture(),
43+
}
44+
}
45+
}
46+
};
47+
}
48+
pub(crate) use impl_from_err;

packages/std/src/errors/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
mod backtrace;
12
mod recover_pubkey_error;
23
mod std_error;
34
mod system_error;
45
mod verification_error;
56

7+
pub(crate) use backtrace::{impl_from_err, BT};
68
pub use recover_pubkey_error::RecoverPubkeyError;
79
pub use std_error::{
810
CheckedFromRatioError, CheckedMultiplyFractionError, CheckedMultiplyRatioError,

packages/std/src/errors/recover_pubkey_error.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use core::fmt::Debug;
22
#[cfg(not(target_arch = "wasm32"))]
33
use cosmwasm_crypto::CryptoError;
4-
#[cfg(feature = "backtraces")]
5-
use std::backtrace::Backtrace;
4+
5+
use super::BT;
66
use thiserror::Error;
77

88
#[derive(Error, Debug)]
@@ -14,19 +14,15 @@ pub enum RecoverPubkeyError {
1414
#[error("Invalid recovery parameter. Supported values: 0 and 1.")]
1515
InvalidRecoveryParam,
1616
#[error("Unknown error: {error_code}")]
17-
UnknownErr {
18-
error_code: u32,
19-
#[cfg(feature = "backtraces")]
20-
backtrace: Backtrace,
21-
},
17+
UnknownErr { error_code: u32, backtrace: BT },
2218
}
2319

2420
impl RecoverPubkeyError {
2521
pub fn unknown_err(error_code: u32) -> Self {
2622
RecoverPubkeyError::UnknownErr {
2723
error_code,
28-
#[cfg(feature = "backtraces")]
29-
backtrace: Backtrace::capture(),
24+
25+
backtrace: BT::capture(),
3026
}
3127
}
3228
}

0 commit comments

Comments
 (0)