Skip to content
This repository was archived by the owner on Aug 16, 2021. It is now read-only.

Commit 17963ae

Browse files
authored
Merge pull request #20 from brson/next
Bump to 0.4.0
2 parents e091699 + 4395720 commit 17963ae

File tree

5 files changed

+21
-235
lines changed

5 files changed

+21
-235
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# 0.4.0
2+
3+
- [Remove the foreign link description and forward to the foreign error](https://github.com/brson/error-chain/pull/19)
4+
- [Allow missing sections](https://github.com/brson/error-chain/pull/17)
5+
6+
Contributors: Brian Anderson, Taylor Cramer
7+
18
# 0.3.0
29

310
- [Forward Display implementation for foreign errors](https://github.com/brson/error-chain/pull/13)

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22

33
name = "error-chain"
4-
version = "0.3.0"
4+
version = "0.4.0"
55
authors = [ "Brian Anderson <banderson@mozilla.com>",
66
"Paul Colomiets <paul@colomiets.name>",
77
"Colin Kiegel <kiegel@gmx.de>"]

README.md

Lines changed: 4 additions & 227 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,16 @@
33

44
# error-chain - Consistent error handling for Rust
55

6-
The [error-chain crate](https://crates.io/crates/error-chain)
7-
([docs](http://brson.github.io/error-chain/index.html)) is a new crate
8-
for dealing with Rust error boilerplate. It provides a few unique
9-
features:
6+
`error-chain` is a crate for dealing with Rust error boilerplate. It
7+
provides a few unique features:
108

119
* No error is ever discarded. This library primarily makes it easy to
1210
"chain" errors with the `chain_err` method.
1311
* Introducing new errors is trivial. Simple errors can be introduced
1412
at the error site with just a string.
1513
* Errors create and propagate backtraces.
1614

17-
I think the lack of the above are widespread problems with Rust error
18-
handling, so I'm interested to hear what people think about this
19-
solution. It is inspired by
20-
[quick-error](https://github.com/tailhook/quick-error) (and in fact
21-
includes a hacked up version of it for internal use) as well as
22-
Cargo's internal error handling techniques. This library is used by
23-
[rustup](https://github.com/rust-lang-nursery/rustup.rs) for error
24-
handling.
25-
26-
One note about usage that isn't included in the docs: the
27-
`chain_error!` macro recurses deeply, so you'll probably need to use
28-
the little-known `#![recursion_limit = "1024"]` macro on crates that
29-
import it.
30-
31-
For detailed usage information read [the
32-
docs](http://brson.github.io/error-chain/index.html),
33-
which are reproduced in part below.
15+
[Documentation](http://brson.github.io/error-chain/index.html).
3416

3517
## Quick start
3618

@@ -62,13 +44,7 @@ mod errors;
6244
Add a file for that module called `errors.rs` and put this inside:
6345

6446
```rust
65-
error_chain! {
66-
links { }
67-
68-
foreign_links { }
69-
70-
errors { }
71-
}
47+
error_chain! { }
7248
```
7349

7450
That's the setup. Now when writing modules for your crate,
@@ -90,205 +66,6 @@ fn do_error_prone_work() -> Result<()> {
9066
}
9167
```
9268

93-
## Declaring error types
94-
95-
Generally, you define one family of error types per crate, though it's
96-
also perfectly fine to define error types on a finer-grained basis,
97-
such as per module.
98-
99-
Assuming you are using crate-level error types, typically you will
100-
define an `errors` module and inside it call `error_chain!`:
101-
102-
```rust
103-
// Define the error types and conversions for this crate
104-
error_chain! {
105-
// The type defined for this error. These are the conventional
106-
// and recommended names, but they can be arbitrarily chosen.
107-
// It is also possible to leave this block out entirely, or
108-
// leave it empty, and these names will be used automatically.
109-
types {
110-
Error, ErrorKind, ChainErr, Result;
111-
}
112-
113-
// Automatic conversions between this error chain and other
114-
// error chains. In this case, it will e.g. generate an
115-
// `ErrorKind` variant called `Dist` which in turn contains
116-
// the `rustup_dist::ErrorKind`, with conversions from
117-
// `rustup_dist::Error`.
118-
//
119-
// This section can be empty.
120-
links {
121-
rustup_dist::Error, rustup_dist::ErrorKind, Dist;
122-
rustup_utils::Error, rustup_utils::ErrorKind, Utils;
123-
}
124-
125-
// Automatic conversions between this error chain and other
126-
// error types not defined by the `error_chain!`. These will be
127-
// wrapped in a new error with, in this case, the
128-
// `ErrorKind::Temp` variant. The description and cause will
129-
// forward to the description and cause of the original error.
130-
//
131-
// This section can be empty.
132-
foreign_links {
133-
temp::Error, Temp;
134-
}
135-
136-
// Define additional `ErrorKind` variants. The syntax here is
137-
// the same as `quick_error!`, but the `from()` and `cause()`
138-
// syntax is not supported.
139-
errors {
140-
InvalidToolchainName(t: String) {
141-
description("invalid toolchain name")
142-
display("invalid toolchain name: '{}'", t)
143-
}
144-
}
145-
}
146-
```
147-
148-
This populates the the module with a number of definitions, the most
149-
important of which are the `Error` type and the `ErrorKind` type. They
150-
look something like the following:
151-
152-
```rust
153-
use std::error::Error as StdError;
154-
use std::sync::Arc;
155-
156-
#[derive(Debug)]
157-
pub struct Error(pub ErrorKind,
158-
pub Option<Box<StdError + Send>>,
159-
pub Arc<error_chain::Backtrace>);
160-
161-
impl Error {
162-
pub fn kind(&self) -> &ErrorKind { ... }
163-
pub fn into_kind(self) -> ErrorKind { ... }
164-
pub fn iter(&self) -> error_chain::ErrorChainIter { ... }
165-
pub fn backtrace(&self) -> &error_chain::Backtrace { ... }
166-
}
167-
168-
impl StdError for Error { ... }
169-
impl Display for Error { ... }
170-
171-
#[derive(Debug)]
172-
pub enum ErrorKind {
173-
Msg(String),
174-
Dist(rustup_dist::ErrorKind),
175-
Utils(rustup_utils::ErrorKind),
176-
Temp,
177-
InvalidToolchainName(String),
178-
}
179-
```
180-
181-
This is the basic error structure. You can see that `ErrorKind` has
182-
been populated in a variety of ways. All `ErrorKind`s get a `Msg`
183-
variant for basic errors. When strings are converted to `ErrorKind`s
184-
they become `ErrorKind::Msg`. The "links" defined in the macro are
185-
expanded to `Dist` and `Utils` variants, and the "foreign links" to
186-
the `Temp` variant.
187-
188-
Both types come with a variety of `From` conversions as well: `Error`
189-
can be created from `ErrorKind`, from `&str` and `String`, and from
190-
the "link" and "foreign_link" error types. `ErrorKind` can be created
191-
from the corresponding `ErrorKind`s of the link types, as wall as from
192-
`&str` and `String`.
193-
194-
`into()` and `From::from` are used heavily to massage types into the
195-
right shape. Which one to use in any specific case depends on the
196-
influence of type inference, but there are some patterns that arise
197-
frequently.
198-
199-
## Chaining errors
200-
201-
This is the focus of the crate's design. To extend the error chain:
202-
203-
```
204-
use errors::ChainErr;
205-
try!(do_something().chain_err(|| "something went wrong"));
206-
```
207-
208-
`chain_err` can be called on any `Result` type where the contained
209-
error type implements `std::error::Error + Send + 'static`. If the
210-
`Result` is an `Err` then `chain_err` evaluates the closure, which
211-
returns *some type that can be converted to `ErrorKind`*, boxes the
212-
original error to store as the cause, then returns a new error
213-
containing the original error.
214-
215-
The above example turns a string into an error, but you could also write e.g.
216-
217-
```
218-
try!(do_something().chain_err(|| ErrorKind::Foo));
219-
```
220-
221-
## Returning new errors
222-
223-
Introducing new error chains, with a string message:
224-
225-
```rust
226-
fn foo() -> Result<()> {
227-
Err("foo error!".into())
228-
}
229-
```
230-
231-
Introducing new error chains, with an `ErrorKind`:
232-
233-
```rust
234-
fn foo() -> Result<()> {
235-
Err(ErrorKind::FooError.into())
236-
}
237-
```
238-
239-
Note that the return type is is the typedef `Result`, which is defined
240-
by the macro as `pub type Result<T> = ::std::result::Result<T,
241-
Error>`. Note that in both cases `.into()` is called to convert a type
242-
into the `Error` type: both strings and `ErrorKind` have `From`
243-
conversions to turn them into `Error`.
244-
245-
When the error is emitted inside a `try!` macro or behind the `?`
246-
operator, then the explicit conversion isn't needed, since the
247-
behavior of `try!` will automatically convert `Err(ErrorKind)` to
248-
`Err(Error)`. So the below is equivalent to the previous:
249-
250-
```rust
251-
fn foo() -> Result<()> {
252-
Ok(try!(Err(ErrorKind::FooError)))
253-
}
254-
255-
fn bar() -> Result<()> {
256-
Ok(try!(Err("bogus!")))
257-
}
258-
```
259-
260-
## Foreign links
261-
262-
Errors that do not conform to the same conventions as this library can
263-
still be included in the error chain. They are considered "foreign
264-
errors", and are declared using the `foreign_links` block of the
265-
`error_chain!` macro. `Error`s are automatically created from foreign
266-
errors by the `try!` macro.
267-
268-
Foreign links and regular links have one crucial difference: `From`
269-
conversions for regular links *do not introduce a new error into the
270-
error chain*, while conversions for foreign links *always introduce a
271-
new error into the error chain*. So for the example above all errors
272-
deriving from the `temp::Error` type will be presented to the user as
273-
a new `ErrorKind::Temp` variant, and the cause will be the original
274-
`temp::Error` error. In contrast, when `rustup_utils::Error` is
275-
converted to `Error` the two `ErrorKinds` are converted between each
276-
other to create a new `Error` but the old error is discarded; there is
277-
no "cause" created from the original error.
278-
279-
## Backtraces
280-
281-
The earliest non-foreign error to be generated creates a single
282-
backtrace, which is passed through all `From` conversions and
283-
`chain_err` invocations of compatible types. To read the backtrace
284-
just call the `backtrace()` method.
285-
286-
## Iteration
287-
288-
The `iter` method returns an iterator over the chain of error
289-
boxes. [See how rustup uses this during error
290-
reporting](https://github.com/rust-lang-nursery/rustup.rs/blob/master/src/rustup-cli/common.rs#L344).
291-
29269
## License
29370

29471
MIT/Apache-2.0

src/lib.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,7 @@
8484
//! Add a file for that module called `errors.rs` and put this inside:
8585
//!
8686
//! ```ignore
87-
//! error_chain! {
88-
//! links { }
89-
//!
90-
//! foreign_links { }
91-
//!
92-
//! errors { }
93-
//! }
87+
//! error_chain! { }
9488
//! ```
9589
//!
9690
//! That's the setup. Now when writing modules for your crate,
@@ -166,6 +160,9 @@
166160
//! }
167161
//! ```
168162
//!
163+
//! Each section, `types`, `links`, `foreign_links`, and `errors` may
164+
//! be omitted if it is empty.
165+
//!
169166
//! This populates the module with a number of definitions,
170167
//! the most important of which are the `Error` type
171168
//! and the `ErrorKind` type. They look something like the

tests/tests.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ fn smoke_test_7() {
104104
}
105105
}
106106

107+
#[test]
108+
fn empty() {
109+
error_chain! { }
110+
}
111+
107112
#[cfg(test)]
108113
mod foreign_link_test {
109114

0 commit comments

Comments
 (0)