Skip to content

Commit 9b59e51

Browse files
committed
Use thiserror instead of snafu in std
1 parent 1cc2276 commit 9b59e51

File tree

17 files changed

+104
-53
lines changed

17 files changed

+104
-53
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
- Remove the previously deprecated `StdError::Unauthorized`. Contract specific
88
errors should be implemented using custom error types now (see
99
[migration guide](./MIGRATING.md) 0.10 -> 0.11).
10+
- Use dependency `thiserror` instead of `snafu` to implement `StdError`. Along
11+
with this change, the `backtraces` feature now requires Rust nightly.
12+
- Rename `StdError::ParseErr::source` to `StdError::ParseErr::source_type` and
13+
`StdError::SerializeErr::target` to `StdError::SerializeErr::target_type` to
14+
work around speacial treatment of the field name `source` in thiserror.
1015

1116
**cosmwasm-vm**
1217

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MIGRATING.md

+19
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,25 @@ This guide explains what is needed to upgrade contracts when migrating over
44
major releases of `cosmwasm`. Note that you can also view the
55
[complete CHANGELOG](./CHANGELOG.md) to understand the differences.
66

7+
## 0.11 -> 0.12
8+
9+
- In your contract's `.cargo/config` remove `--features backtraces`, which is
10+
now available in Rust nightly only:
11+
12+
```diff
13+
@@ -1,6 +1,6 @@
14+
[alias]
15+
wasm = "build --release --target wasm32-unknown-unknown"
16+
wasm-debug = "build --target wasm32-unknown-unknown"
17+
-unit-test = "test --lib --features backtraces"
18+
+unit-test = "test --lib"
19+
integration-test = "test --test integration"
20+
schema = "run --example schema"
21+
```
22+
23+
In order to use backtraces for debugging, run
24+
`RUST_BACKTRACE=1 cargo +nightly unit-test --features backtraces`.
25+
726
## 0.10 -> 0.11
827

928
- Contracts now support any custom error type `E: ToString + From<StdError>`.

contracts/burner/.cargo/config

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[alias]
22
wasm = "build --release --target wasm32-unknown-unknown"
33
wasm-debug = "build --target wasm32-unknown-unknown"
4-
unit-test = "test --lib --features backtraces"
4+
unit-test = "test --lib"
55
integration-test = "test --test integration"
66
schema = "run --example schema"

contracts/burner/Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/hackatom/.cargo/config

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[alias]
22
wasm = "build --release --target wasm32-unknown-unknown"
33
wasm-debug = "build --target wasm32-unknown-unknown"
4-
unit-test = "test --lib --features backtraces"
4+
unit-test = "test --lib"
55
integration-test = "test --test integration"
66
schema = "run --example schema"

contracts/hackatom/Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/queue/.cargo/config

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[alias]
22
wasm = "build --release --target wasm32-unknown-unknown"
33
wasm-debug = "build --target wasm32-unknown-unknown"
4-
unit-test = "test --lib --features backtraces"
4+
unit-test = "test --lib"
55
integration-test = "test --test integration"
66
schema = "run --example schema"

contracts/queue/Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/reflect/.cargo/config

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[alias]
22
wasm = "build --release --target wasm32-unknown-unknown"
33
wasm-debug = "build --target wasm32-unknown-unknown"
4-
unit-test = "test --lib --features backtraces"
4+
unit-test = "test --lib"
55
integration-test = "test --test integration"
66
schema = "run --example schema"

contracts/reflect/Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/staking/.cargo/config

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[alias]
22
wasm = "build --release --target wasm32-unknown-unknown"
33
wasm-debug = "build --target wasm32-unknown-unknown"
4-
unit-test = "test --lib --features backtraces"
4+
unit-test = "test --lib"
55
integration-test = "test --test integration"
66
schema = "run --example schema"

contracts/staking/Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/std/.cargo/config

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[alias]
22
wasm = "build --release --target wasm32-unknown-unknown"
33
wasm-debug = "build --target wasm32-unknown-unknown"
4-
unit-test = "test --lib --features backtraces"
4+
unit-test = "test --lib"
55
schema = "run --example schema"

packages/std/Cargo.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ iterator = []
2525
staking = []
2626
# backtraces provides much better context at runtime errors (in non-wasm code)
2727
# at the cost of a bit of code size and performance.
28-
backtraces = ["snafu/backtraces"]
28+
# This feature requires Rust nightly because it depends on the unstable backtrace feature.
29+
backtraces = []
2930

3031
[dependencies]
3132
base64 = "0.11.0"
3233
serde-json-wasm = { version = "0.2.1" }
3334
schemars = "0.7"
3435
serde = { version = "1.0.103", default-features = false, features = ["derive", "alloc"] }
35-
snafu = { version = "0.6.6" }
36+
thiserror = "1.0"
3637

3738
[dev-dependencies]
3839
cosmwasm-schema = { path = "../schema" }

packages/std/src/errors/std_error.rs

+63-39
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use snafu::Snafu;
1+
#[cfg(feature = "backtraces")]
2+
use std::backtrace::Backtrace;
3+
use thiserror::Error;
24

35
/// Structured error type for init, handle and query.
46
///
@@ -15,99 +17,117 @@ use snafu::Snafu;
1517
/// Checklist for adding a new error:
1618
/// - Add enum case
1719
/// - Add creator function in std_error_helpers.rs
18-
#[derive(Debug, Snafu)]
19-
#[non_exhaustive]
20+
#[derive(Error, Debug)]
2021
pub enum StdError {
2122
/// Whenever there is no specific error type available
22-
#[snafu(display("Generic error: {}", msg))]
23+
#[error("Generic error: {msg}")]
2324
GenericErr {
2425
msg: String,
25-
backtrace: Option<snafu::Backtrace>,
26+
#[cfg(feature = "backtraces")]
27+
backtrace: Backtrace,
2628
},
27-
#[snafu(display("Invalid Base64 string: {}", msg))]
29+
#[error("Invalid Base64 string: {msg}")]
2830
InvalidBase64 {
2931
msg: String,
30-
backtrace: Option<snafu::Backtrace>,
32+
#[cfg(feature = "backtraces")]
33+
backtrace: Backtrace,
3134
},
3235
/// Whenever UTF-8 bytes cannot be decoded into a unicode string, e.g. in String::from_utf8 or str::from_utf8.
33-
#[snafu(display("Cannot decode UTF8 bytes into string: {}", msg))]
36+
#[error("Cannot decode UTF8 bytes into string: {msg}")]
3437
InvalidUtf8 {
3538
msg: String,
36-
backtrace: Option<snafu::Backtrace>,
39+
#[cfg(feature = "backtraces")]
40+
backtrace: Backtrace,
3741
},
38-
#[snafu(display("{} not found", kind))]
42+
#[error("{kind} not found")]
3943
NotFound {
4044
kind: String,
41-
backtrace: Option<snafu::Backtrace>,
45+
#[cfg(feature = "backtraces")]
46+
backtrace: Backtrace,
4247
},
43-
#[snafu(display("Error parsing into type {}: {}", target, msg))]
48+
#[error("Error parsing into type {target_type}: {msg}")]
4449
ParseErr {
4550
/// the target type that was attempted
46-
target: String,
51+
target_type: String,
4752
msg: String,
48-
backtrace: Option<snafu::Backtrace>,
53+
#[cfg(feature = "backtraces")]
54+
backtrace: Backtrace,
4955
},
50-
#[snafu(display("Error serializing type {}: {}", source, msg))]
56+
#[error("Error serializing type {source_type}: {msg}")]
5157
SerializeErr {
5258
/// the source type that was attempted
53-
#[snafu(source(false))]
54-
source: String,
59+
source_type: String,
5560
msg: String,
56-
backtrace: Option<snafu::Backtrace>,
61+
#[cfg(feature = "backtraces")]
62+
backtrace: Backtrace,
5763
},
58-
#[snafu(display("Cannot subtract {} from {}", subtrahend, minuend))]
64+
#[error("Cannot subtract {subtrahend} from {minuend}")]
5965
Underflow {
6066
minuend: String,
6167
subtrahend: String,
62-
backtrace: Option<snafu::Backtrace>,
68+
#[cfg(feature = "backtraces")]
69+
backtrace: Backtrace,
6370
},
6471
}
6572

6673
impl StdError {
6774
pub fn generic_err<S: Into<String>>(msg: S) -> Self {
68-
GenericErr { msg: msg.into() }.build()
75+
StdError::GenericErr {
76+
msg: msg.into(),
77+
#[cfg(feature = "backtraces")]
78+
backtrace: Backtrace::capture(),
79+
}
6980
}
7081

7182
pub fn invalid_base64<S: ToString>(msg: S) -> Self {
72-
InvalidBase64 {
83+
StdError::InvalidBase64 {
7384
msg: msg.to_string(),
85+
#[cfg(feature = "backtraces")]
86+
backtrace: Backtrace::capture(),
7487
}
75-
.build()
7688
}
7789

7890
pub fn invalid_utf8<S: ToString>(msg: S) -> Self {
79-
InvalidUtf8 {
91+
StdError::InvalidUtf8 {
8092
msg: msg.to_string(),
93+
#[cfg(feature = "backtraces")]
94+
backtrace: Backtrace::capture(),
8195
}
82-
.build()
8396
}
8497

8598
pub fn not_found<S: Into<String>>(kind: S) -> Self {
86-
NotFound { kind: kind.into() }.build()
99+
StdError::NotFound {
100+
kind: kind.into(),
101+
#[cfg(feature = "backtraces")]
102+
backtrace: Backtrace::capture(),
103+
}
87104
}
88105

89106
pub fn parse_err<T: Into<String>, M: ToString>(target: T, msg: M) -> Self {
90-
ParseErr {
91-
target: target.into(),
107+
StdError::ParseErr {
108+
target_type: target.into(),
92109
msg: msg.to_string(),
110+
#[cfg(feature = "backtraces")]
111+
backtrace: Backtrace::capture(),
93112
}
94-
.build()
95113
}
96114

97115
pub fn serialize_err<S: Into<String>, M: ToString>(source: S, msg: M) -> Self {
98-
SerializeErr {
99-
source: source.into(),
116+
StdError::SerializeErr {
117+
source_type: source.into(),
100118
msg: msg.to_string(),
119+
#[cfg(feature = "backtraces")]
120+
backtrace: Backtrace::capture(),
101121
}
102-
.build()
103122
}
104123

105124
pub fn underflow<U: ToString>(minuend: U, subtrahend: U) -> Self {
106-
Underflow {
125+
StdError::Underflow {
107126
minuend: minuend.to_string(),
108127
subtrahend: subtrahend.to_string(),
128+
#[cfg(feature = "backtraces")]
129+
backtrace: Backtrace::capture(),
109130
}
110-
.build()
111131
}
112132
}
113133

@@ -206,8 +226,10 @@ mod test {
206226
fn parse_err_works() {
207227
let error = StdError::parse_err("Book", "Missing field: title");
208228
match error {
209-
StdError::ParseErr { target, msg, .. } => {
210-
assert_eq!(target, "Book");
229+
StdError::ParseErr {
230+
target_type, msg, ..
231+
} => {
232+
assert_eq!(target_type, "Book");
211233
assert_eq!(msg, "Missing field: title");
212234
}
213235
_ => panic!("expect different error"),
@@ -218,8 +240,10 @@ mod test {
218240
fn serialize_err_works() {
219241
let error = StdError::serialize_err("Book", "Content too long");
220242
match error {
221-
StdError::SerializeErr { source, msg, .. } => {
222-
assert_eq!(source, "Book");
243+
StdError::SerializeErr {
244+
source_type, msg, ..
245+
} => {
246+
assert_eq!(source_type, "Book");
223247
assert_eq!(msg, "Content too long");
224248
}
225249
_ => panic!("expect different error"),
@@ -264,7 +288,7 @@ mod test {
264288
let embedded = format!("Debug message: {:?}", error);
265289
assert_eq!(
266290
embedded,
267-
r#"Debug message: Underflow { minuend: "3", subtrahend: "5", backtrace: None }"#
291+
r#"Debug message: Underflow { minuend: "3", subtrahend: "5" }"#
268292
);
269293
}
270294

packages/std/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![cfg_attr(feature = "backtraces", feature(backtrace))]
2+
13
// Exposed on all platforms
24

35
mod addresses;

0 commit comments

Comments
 (0)