Bug 1405877 - Update Rust deps for media/audioipc. r=kamidphish

--HG--
rename : third_party/rust/error-chain/src/quick_error.rs => third_party/rust/error-chain/src/impl_error_chain_kind.rs
This commit is contained in:
Matthew Gregan 2017-12-20 14:51:11 +13:00
parent 3d317e6af8
commit 86594ab667
22 changed files with 901 additions and 275 deletions

View File

@ -1 +1 @@
{"files":{".travis.yml":"d56246d6c8796c638b5012c2d7a91d9b6ec101b6a47128e2d4bfa957c1c784e8","CHANGELOG.md":"4f602de0b17e0d0121371482dfcf3caf2265b70bf92e8b5db1cba5dd8f391469","Cargo.toml":"8e4d1f0b25be862107a6938190c9817cd7ea516db50e688de1d0fe87519105ee","README.md":"6771ca940645b2f7e7a018c8cd25b25f8bf35786e229b54fa2fded1f2d0ae411","examples/all.rs":"6f073ea0e3db541a4eefb41436fc03a121a1f932fd6a2798b485a72d64bd1a3c","examples/doc.rs":"574948eb776c3d363f5cff9a48015bab6c17828c7306dc3eb8818afa90a31a83","examples/quickstart.rs":"c3142d5139d89c3861b119507a372fba47ac3d7df61aa90b068d518dea8fd6f6","examples/size.rs":"7922acd891dfd06f1d36308a3ccdf03def2646b2f39bfd1b15cf2896247bad8f","src/error_chain.rs":"d0cb3e4a93f9c358e4bd18ab8443573e57ace15442f4697ad95963d10408f882","src/example_generated.rs":"7d5220020aada7def70d3b3e396dadb0b139ed104b1253d06ac53f48517ec668","src/lib.rs":"0d1c972252dd1df3117ddf0a71a4734cdb350b41376e09cbe4b868afb0e2762b","src/quick_error.rs":"1889b9ca1f7a5e9124275fd5da81e709d0d6bd3b06915bf320c23d4c4f083301","src/quick_main.rs":"106a0cf44a6a2fbb9fb1d8932d234f43cd7af230fc6685b28f6b9dfaca2a3210","tests/quick_main.rs":"1d6a726856b954d4cffddab00602583921972ceeeb2bf7ba9ebbac6a51584b53","tests/tests.rs":"67b6acf87f4986fa013f018195e3becd6dd63d8101a7af07a417e8e526cf50ad"},"package":"d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"} {"files":{".travis.yml":"6dcf8fe7a4ef9f228cabc1a9179b3084c8be6dd09b9b838dbf4019d113e1bbcf","CHANGELOG.md":"010cba4f5cdf9607eb744e83a666a3642d6c1aae5d467c67978e97a7f7e86bd8","Cargo.toml":"d8d10d260671883629d2b7e6c5daca5eb2b49b8b1c88345e530462ea1a2e6913","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c43864d39cedab9a1b2aa3d5e480cb58f74cac0b07756670a30c683ce34976a1","README.md":"d63912fd7a5a1a2b1d21edde3cee58cbe422c29b9fcdcc7b8ba2264bf15825b5","examples/all.rs":"cf8422ea6fdb61dbe9ddbb2db51daba48768e3b1d81c5f9e454371c258954cfb","examples/chain_err.rs":"fbb6f90397d5e621e4982d224caf3d419a3c1aaa50f07e5c9c617a9352cfb81f","examples/doc.rs":"790ad6877c91e4e5b2d78829c58702100dcccf3eac2279940257691420cdff03","examples/quickstart.rs":"ca471b3c310d40e5f5dc07db2bfbfcedb71dfc1e25021a6383a9810b24e8fc40","examples/size.rs":"a67ba47b254fb899cb0ecf809e95f75649bb0e401feece9485a2064e223602ab","src/bin/has_backtrace.rs":"eedf028ff206938760a53e91d13534b6ad6780b2b6635f405b7896125484a869","src/error_chain.rs":"5fc674d965746f3ea1a6ea65f82352c40b83439004480bf5a338748a90e476cc","src/example_generated.rs":"95a1e191917740885286f199186674ed575d807077b57dffe6388a4fe2e1ba98","src/impl_error_chain_kind.rs":"538c6f7a2382d555f809c4d7f33e739dff7aa75b2fb3c1629ca2afaa38ff4279","src/lib.rs":"0adc37e316f45d57d56d76245c76942d2a894643c4d2da744639d33c3cd99099","src/quick_main.rs":"472f0b90b11d346cbceec5a95da78fabda0fb55e7e019dc62ac8ff0c206841ea","tests/quick_main.rs":"39a1113cc0d30e5b265e4139cda36f910f8c534a4409e99a9a506a0e88e58f19","tests/tests.rs":"2b76317571651999c294c639088ec7d764c27721d802ea6bc624cfdf31619623"},"package":"ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"}

View File

@ -5,7 +5,7 @@ rust:
- nightly - nightly
# Oldest supported version for all features. # Oldest supported version for all features.
# Use of https://github.com/rust-lang/rfcs/pull/16 # Use of https://github.com/rust-lang/rfcs/pull/16
- 1.13.0 - 1.14.0
# Oldest supported version as dependency, with no features, tests, or examples. # Oldest supported version as dependency, with no features, tests, or examples.
- 1.10.0 - 1.10.0
@ -35,6 +35,7 @@ env:
global: global:
- secure: ncxJbvJM1vCZfcEftjsFKJMxxhKLgWKaR8Go9AMo0VB5fB2XVW/6NYO5bQEEYpOf1Nc/+2FbI2+Dkz0S/mJpUcNSfBgablCHgwU2sHse7KsoaqfHj2mf1E3exjzSHoP96hPGicC5zAjSXFjCgJPOUSGqqRaJ7z5AsJLhJT6LuK7QpvwPBZzklUN8T+n1sVmws8TNmRIbaniq/q6wYHANHcy6Dl59dx4sKwniUGiZdUhCiddVpoxbECSxc0A8mN2pk7/aW+WGxK3goBs5ZF7+JXF318F62pDcXQmR5CX6WdpenIcJ25g1Vg1WhQ4Ifpe17CN0bfxV8ShuzrQUThCDMffZCo9XySBtODdEowwK1UIpjnFLfIxjOs45Cd8o3tM2j0CfvtnjOz6BCdUU0qiwNPPNx0wFkx3ZiOfSh+FhBhvyPM12HN2tdN0esgVBItFmEci+sSIIXqjVL6DNiu5zTjbu0bs6COwlUWdmL6vmsZtq5tl7Cno9+C3szxRVAkShGydd04l9NYjqNEzTa1EPG50OsnVRKGdRiFzSxhc3BWExNKvcQ4v867t6/PpPkW6s4oXmYI3+De+8O7ExWc6a4alcrDXKlMs5fCb5Pcd4Ju9kowcjkoJo5yf2wW3Ox5R8SJpaEEpvyhx5O/qtIxjhHNzeo8Wsr/6gdNDv20r91TI= - secure: ncxJbvJM1vCZfcEftjsFKJMxxhKLgWKaR8Go9AMo0VB5fB2XVW/6NYO5bQEEYpOf1Nc/+2FbI2+Dkz0S/mJpUcNSfBgablCHgwU2sHse7KsoaqfHj2mf1E3exjzSHoP96hPGicC5zAjSXFjCgJPOUSGqqRaJ7z5AsJLhJT6LuK7QpvwPBZzklUN8T+n1sVmws8TNmRIbaniq/q6wYHANHcy6Dl59dx4sKwniUGiZdUhCiddVpoxbECSxc0A8mN2pk7/aW+WGxK3goBs5ZF7+JXF318F62pDcXQmR5CX6WdpenIcJ25g1Vg1WhQ4Ifpe17CN0bfxV8ShuzrQUThCDMffZCo9XySBtODdEowwK1UIpjnFLfIxjOs45Cd8o3tM2j0CfvtnjOz6BCdUU0qiwNPPNx0wFkx3ZiOfSh+FhBhvyPM12HN2tdN0esgVBItFmEci+sSIIXqjVL6DNiu5zTjbu0bs6COwlUWdmL6vmsZtq5tl7Cno9+C3szxRVAkShGydd04l9NYjqNEzTa1EPG50OsnVRKGdRiFzSxhc3BWExNKvcQ4v867t6/PpPkW6s4oXmYI3+De+8O7ExWc6a4alcrDXKlMs5fCb5Pcd4Ju9kowcjkoJo5yf2wW3Ox5R8SJpaEEpvyhx5O/qtIxjhHNzeo8Wsr/6gdNDv20r91TI=
- TRAVIS_CARGO_NIGHTLY_FEATURE="" - TRAVIS_CARGO_NIGHTLY_FEATURE=""
- RUSTFLAGS="-D warnings"
matrix: matrix:
- FEATURES=--features=backtrace - FEATURES=--features=backtrace
- FEATURES=--no-default-features - FEATURES=--no-default-features

View File

@ -1,22 +1,42 @@
# Unreleased # Unreleased
# 0.11.0
- Change last rust version supported to 1.14
- [Cache whether RUST_BACKTRACE is enabled in a relaxed atomic static.](https://github.com/rust-lang-nursery/error-chain/pull/210)
- [Mask the `quick_error` macro from the doc](https://github.com/rust-lang-nursery/error-chain/pull/210)
- [Make generated `ErrorKind` enums non-exhaustive](https://github.com/rust-lang-nursery/error-chain/pull/193)
- All 0.11.0-rc.2 changes
# 0.11.0-rc.2
- [Make `ErrorChainIter`'s field private](https://github.com/rust-lang-nursery/error-chain/issues/178)
- [Rename `ErrorChainIter` to `Iter`](https://github.com/rust-lang-nursery/error-chain/issues/168)
- [Implement `Debug` for `ErrorChainIter`](https://github.com/rust-lang-nursery/error-chain/issues/169)
- [Rename `ChainedError::display` to `display_chain`](https://github.com/rust-lang-nursery/error-chain/issues/180)
- [Add a new method for `Error`: `chain_err`.](https://github.com/rust-lang-nursery/error-chain/pull/141)
- [Allow `chain_err` to be used on `Option<T>`](https://github.com/rust-lang-nursery/error-chain/pull/156)
- [Add support for creating an error chain on boxed trait errors (`Box<Error>`)](https://github.com/rust-lang-nursery/error-chain/pull/156)
- [Remove lint for unused doc comment.](https://github.com/rust-lang-nursery/error-chain/pull/199)
- [Hide error_chain_processed macro from documentation.](https://github.com/rust-lang-nursery/error-chain/pull/212)
# 0.10.0 # 0.10.0
- [Add a new constructor for `Error`: `with_chain`.](https://github.com/brson/error-chain/pull/126) - [Add a new constructor for `Error`: `with_chain`.](https://github.com/rust-lang-nursery/error-chain/pull/126)
- [Add the `ensure!` macro.](https://github.com/brson/error-chain/pull/135) - [Add the `ensure!` macro.](https://github.com/rust-lang-nursery/error-chain/pull/135)
# 0.9.0 # 0.9.0
- Revert [Add a `Sync` bound to errors](https://github.com/brson/error-chain/pull/110) - Revert [Add a `Sync` bound to errors](https://github.com/rust-lang-nursery/error-chain/pull/110)
# 0.8.1 # 0.8.1
- Add crates.io categorie. - Add crates.io category.
# 0.8.0 # 0.8.0
- [Add a `Sync` bound to errors](https://github.com/brson/error-chain/pull/110) - [Add a `Sync` bound to errors](https://github.com/rust-lang-nursery/error-chain/pull/110)
- [Add `ChainedError::display` to format error chains](https://github.com/brson/error-chain/pull/113) - [Add `ChainedError::display` to format error chains](https://github.com/rust-lang-nursery/error-chain/pull/113)
# 0.7.2 # 0.7.2
@ -26,11 +46,11 @@
# 0.7.1 # 0.7.1
- [Add the `bail!` macro](https://github.com/brson/error-chain/pull/76) - [Add the `bail!` macro](https://github.com/rust-lang-nursery/error-chain/pull/76)
# 0.7.0 # 0.7.0
- [Rollback several design changes to fix regressions](https://github.com/brson/error-chain/pull/75) - [Rollback several design changes to fix regressions](https://github.com/rust-lang-nursery/error-chain/pull/75)
- New `Variant(Error) #[attrs]` for `links` and `foreign_links`. - New `Variant(Error) #[attrs]` for `links` and `foreign_links`.
- Hide implementation details from the doc. - Hide implementation details from the doc.
- Always generate `Error::backtrace`. - Always generate `Error::backtrace`.
@ -60,41 +80,41 @@
# 0.5.0 # 0.5.0
- [Only generate backtraces with RUST_BACKTRACE set](https://github.com/brson/error-chain/pull/27) - [Only generate backtraces with RUST_BACKTRACE set](https://github.com/rust-lang-nursery/error-chain/pull/27)
- [Fixup matching, disallow repeating "types" section](https://github.com/brson/error-chain/pull/26) - [Fixup matching, disallow repeating "types" section](https://github.com/rust-lang-nursery/error-chain/pull/26)
- [Fix tests on stable/beta](https://github.com/brson/error-chain/pull/28) - [Fix tests on stable/beta](https://github.com/rust-lang-nursery/error-chain/pull/28)
- [Only deploy docs when tagged](https://github.com/brson/error-chain/pull/30) - [Only deploy docs when tagged](https://github.com/rust-lang-nursery/error-chain/pull/30)
Contributors: benaryorg, Brian Anderson, Georg Brandl Contributors: benaryorg, Brian Anderson, Georg Brandl
# 0.4.2 # 0.4.2
- [Fix the resolution of the ErrorKind description method](https://github.com/brson/error-chain/pull/24) - [Fix the resolution of the ErrorKind description method](https://github.com/rust-lang-nursery/error-chain/pull/24)
Contributors: Brian Anderson Contributors: Brian Anderson
# 0.4.1 (yanked) # 0.4.1 (yanked)
- [Fix a problem with resolving methods of the standard Error type](https://github.com/brson/error-chain/pull/22) - [Fix a problem with resolving methods of the standard Error type](https://github.com/rust-lang-nursery/error-chain/pull/22)
Contributors: Brian Anderson Contributors: Brian Anderson
# 0.4.0 (yanked) # 0.4.0 (yanked)
- [Remove the foreign link description and forward to the foreign error](https://github.com/brson/error-chain/pull/19) - [Remove the foreign link description and forward to the foreign error](https://github.com/rust-lang-nursery/error-chain/pull/19)
- [Allow missing sections](https://github.com/brson/error-chain/pull/17) - [Allow missing sections](https://github.com/rust-lang-nursery/error-chain/pull/17)
Contributors: Brian Anderson, Taylor Cramer Contributors: Brian Anderson, Taylor Cramer
# 0.3.0 # 0.3.0
- [Forward Display implementation for foreign errors](https://github.com/brson/error-chain/pull/13) - [Forward Display implementation for foreign errors](https://github.com/rust-lang-nursery/error-chain/pull/13)
Contributors: Brian Anderson, Taylor Cramer Contributors: Brian Anderson, Taylor Cramer
# 0.2.2 # 0.2.2
- [Don't require `types` section in macro invocation](https://github.com/brson/error-chain/pull/8) - [Don't require `types` section in macro invocation](https://github.com/rust-lang-nursery/error-chain/pull/8)
- [Add "quick start" to README](https://github.com/brson/error-chain/pull/9) - [Add "quick start" to README](https://github.com/rust-lang-nursery/error-chain/pull/9)
Contributors: Brian Anderson, Jake Shadle, Nate Mara Contributors: Brian Anderson, Jake Shadle, Nate Mara

View File

@ -1,26 +1,32 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package] [package]
name = "error-chain" name = "error-chain"
version = "0.10.0" version = "0.11.0"
authors = [ "Brian Anderson <banderson@mozilla.com>", authors = ["Brian Anderson <banderson@mozilla.com>", "Paul Colomiets <paul@colomiets.name>", "Colin Kiegel <kiegel@gmx.de>", "Yamakaky <yamakaky@yamaworld.fr>"]
"Paul Colomiets <paul@colomiets.name>",
"Colin Kiegel <kiegel@gmx.de>",
"Yamakaky <yamakaky@yamaworld.fr>"]
description = "Yet another error boilerplate library." description = "Yet another error boilerplate library."
categories = ["rust-patterns"]
documentation = "https://docs.rs/error-chain" documentation = "https://docs.rs/error-chain"
homepage = "https://github.com/brson/error-chain" readme = "README.md"
repository = "https://github.com/brson/error-chain" keywords = ["error"]
categories = ["rust-patterns"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
repository = "https://github.com/rust-lang-nursery/error-chain"
[badges] [dependencies.backtrace]
travis-ci = { repository = "brson/error-chain" } version = "0.3"
optional = true
[features] [features]
default = ["backtrace", "example_generated"]
example_generated = [] example_generated = []
default = ["backtrace", "example_generated"]
[dependencies] [badges.travis-ci]
backtrace = { version = "0.3", optional = true } repository = "rust-lang-nursery/error-chain"

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,26 @@
Copyright (c) 2017 The Error-Chain Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -1,8 +1,8 @@
# error-chain - Consistent error handling for Rust # error-chain - Consistent error handling for Rust
[![Build Status](https://api.travis-ci.org/brson/error-chain.svg?branch=master)](https://travis-ci.org/brson/error-chain) [![Build Status](https://api.travis-ci.org/rust-lang-nursery/error-chain.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/error-chain)
[![Latest Version](https://img.shields.io/crates/v/error-chain.svg)](https://crates.io/crates/error-chain) [![Latest Version](https://img.shields.io/crates/v/error-chain.svg)](https://crates.io/crates/error-chain)
[![License](https://img.shields.io/github/license/brson/error-chain.svg)](https://github.com/brson/error-chain) [![License](https://img.shields.io/github/license/rust-lang-nursery/error-chain.svg)](https://github.com/rust-lang-nursery/error-chain)
`error-chain` makes it easy to take full advantage of Rust's error `error-chain` makes it easy to take full advantage of Rust's error
handling features without the overhead of maintaining boilerplate handling features without the overhead of maintaining boilerplate
@ -12,7 +12,7 @@ error types.
[Documentation (crates.io)](https://docs.rs/error-chain). [Documentation (crates.io)](https://docs.rs/error-chain).
[Documentation (master)](https://brson.github.io/error-chain). [Documentation (master)](https://rust-lang-nursery.github.io/error-chain).
## Quick start ## Quick start
@ -20,7 +20,7 @@ If you just want to set up your new project with error-chain,
follow the [quickstart.rs] template, and read this [intro] follow the [quickstart.rs] template, and read this [intro]
to error-chain. to error-chain.
[quickstart.rs]: https://github.com/brson/error-chain/blob/master/examples/quickstart.rs [quickstart.rs]: https://github.com/rust-lang-nursery/error-chain/blob/master/examples/quickstart.rs
[intro]: http://brson.github.io/2016/11/30/starting-with-error-chain [intro]: http://brson.github.io/2016/11/30/starting-with-error-chain
## Supported Rust version ## Supported Rust version

View File

@ -2,12 +2,12 @@
extern crate error_chain; extern crate error_chain;
pub mod inner { pub mod inner {
error_chain! {} error_chain!{}
} }
#[cfg(feature = "a_feature")] #[cfg(feature = "a_feature")]
pub mod feature { pub mod feature {
error_chain! {} error_chain!{}
} }
error_chain! { error_chain! {

View File

@ -0,0 +1,69 @@
//! Demonstrates usage of `Error::caused` method. This method enables chaining errors
//! like `ResultExt::chain_err` but doesn't require the presence of a `Result` wrapper.
#[macro_use]
extern crate error_chain;
use std::fs::File;
mod errors {
use std::io;
use super::LaunchStage;
error_chain! {
foreign_links {
Io(io::Error) #[doc = "Error during IO"];
}
errors {
Launch(phase: LaunchStage) {
description("An error occurred during startup")
display("Startup aborted: {:?} did not complete successfully", phase)
}
ConfigLoad(path: String) {
description("Config file not found")
display("Unable to read file `{}`", path)
}
}
}
impl From<LaunchStage> for ErrorKind {
fn from(v: LaunchStage) -> Self {
ErrorKind::Launch(v)
}
}
}
pub use errors::*;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LaunchStage {
ConfigLoad,
ConfigParse,
ConfigResolve,
}
/// Read the service config from the file specified.
fn load_config(rel_path: &str) -> Result<()> {
File::open(rel_path)
.map(|_| ())
.chain_err(|| ErrorKind::ConfigLoad(rel_path.to_string()))
}
/// Launch the service.
fn launch(rel_path: &str) -> Result<()> {
load_config(rel_path).map_err(|e| match e {
e @ Error(ErrorKind::ConfigLoad(_), _) => {
e.chain_err(|| LaunchStage::ConfigLoad)
}
e => e.chain_err(|| "Unknown failure"),
})
}
fn main() {
let chain = launch("does_not_exist.json").unwrap_err();
for err in chain.iter() {
println!("{}", err);
}
}

View File

@ -7,8 +7,7 @@ extern crate error_chain;
/// Inner module. /// Inner module.
pub mod inner { pub mod inner {
error_chain! { error_chain!{}
}
} }
error_chain! { error_chain! {

View File

@ -14,14 +14,17 @@ extern crate error_chain;
// `error_chain!` creates. // `error_chain!` creates.
mod errors { mod errors {
// Create the Error, ErrorKind, ResultExt, and Result types // Create the Error, ErrorKind, ResultExt, and Result types
error_chain! { } error_chain!{}
} }
// This only gives access within this module. Make this `pub use errors::*;`
// instead if the types must be accessible from other modules (e.g., within
// a `links` section).
use errors::*; use errors::*;
fn main() { fn main() {
if let Err(ref e) = run() { if let Err(ref e) = run() {
use ::std::io::Write; use std::io::Write;
let stderr = &mut ::std::io::stderr(); let stderr = &mut ::std::io::stderr();
let errmsg = "Error writing to stderr"; let errmsg = "Error writing to stderr";
@ -43,24 +46,24 @@ fn main() {
// The above main gives you maximum control over how the error is // The above main gives you maximum control over how the error is
// formatted. If you don't care (i.e. you want to display the full // formatted. If you don't care (i.e. you want to display the full
// error during an assert) you can just call the `display` method // error during an assert) you can just call the `display_chain` method
// on the error object // on the error object
#[allow(dead_code)] #[allow(dead_code)]
fn alternative_main() { fn alternative_main() {
if let Err(ref e) = run() { if let Err(ref e) = run() {
use std::io::Write; use std::io::Write;
use error_chain::ChainedError; // trait which holds `display` use error_chain::ChainedError; // trait which holds `display_chain`
let stderr = &mut ::std::io::stderr(); let stderr = &mut ::std::io::stderr();
let errmsg = "Error writing to stderr"; let errmsg = "Error writing to stderr";
writeln!(stderr, "{}", e.display()).expect(errmsg); writeln!(stderr, "{}", e.display_chain()).expect(errmsg);
::std::process::exit(1); ::std::process::exit(1);
} }
} }
// Use this macro to auto-generate the main above. You may want to // Use this macro to auto-generate the main above. You may want to
// set the `RUST_BACKTRACE` env variable to see a backtrace. // set the `RUST_BACKTRACE` env variable to see a backtrace.
//quick_main!(run); // quick_main!(run);
// Most functions will return the `Result` type, imported from the // Most functions will return the `Result` type, imported from the

View File

@ -32,9 +32,7 @@ fn main() {
} }
#[cfg(not(feature = "backtrace"))] #[cfg(not(feature = "backtrace"))]
{ {
let state = error_chain::State { let state = error_chain::State { next_error: None };
next_error: None,
};
println!(" State.next_error: {}", size_of_val(&state.next_error)); println!(" State.next_error: {}", size_of_val(&state.next_error));
} }
} }

View File

@ -0,0 +1,18 @@
//! Exits with exit code 0 if backtraces are disabled and 1 if they are enabled.
//! Used by tests to make sure backtraces are available when they should be. Should not be used
//! outside of the tests.
#[macro_use]
extern crate error_chain;
error_chain! {
errors {
MyError
}
}
fn main() {
let err = Error::from(ErrorKind::MyError);
let has_backtrace = err.backtrace().is_some();
::std::process::exit(has_backtrace as i32);
}

View File

@ -1,12 +1,13 @@
/// Prefer to use `error_chain` instead of this macro. /// Prefer to use `error_chain` instead of this macro.
#[doc(hidden)]
#[macro_export] #[macro_export]
macro_rules! error_chain_processed { macro_rules! impl_error_chain_processed {
// Default values for `types`. // Default values for `types`.
( (
types {} types {}
$( $rest: tt )* $( $rest: tt )*
) => { ) => {
error_chain_processed! { impl_error_chain_processed! {
types { types {
Error, ErrorKind, ResultExt, Result; Error, ErrorKind, ResultExt, Result;
} }
@ -21,7 +22,7 @@ macro_rules! error_chain_processed {
} }
$( $rest: tt )* $( $rest: tt )*
) => { ) => {
error_chain_processed! { impl_error_chain_processed! {
types { types {
$error_name, $error_kind_name, $error_name, $error_kind_name,
$result_ext_name; $result_ext_name;
@ -96,8 +97,14 @@ macro_rules! error_chain_processed {
self.kind() self.kind()
} }
fn iter(&self) -> $crate::ErrorChainIter { fn iter(&self) -> $crate::Iter {
$crate::ErrorChainIter(Some(self)) $crate::Iter::new(Some(self))
}
fn chain_err<F, EK>(self, error: F) -> Self
where F: FnOnce() -> EK,
EK: Into<$error_kind_name> {
self.chain_err(error)
} }
fn backtrace(&self) -> Option<&$crate::Backtrace> { fn backtrace(&self) -> Option<&$crate::Backtrace> {
@ -124,10 +131,18 @@ macro_rules! error_chain_processed {
-> $error_name -> $error_name
where E: ::std::error::Error + Send + 'static, where E: ::std::error::Error + Send + 'static,
K: Into<$error_kind_name> K: Into<$error_kind_name>
{
$error_name::with_boxed_chain(Box::new(error), kind)
}
/// Construct a chained error from another boxed error and a kind, and generates a backtrace
pub fn with_boxed_chain<K>(error: Box<::std::error::Error + Send>, kind: K)
-> $error_name
where K: Into<$error_kind_name>
{ {
$error_name( $error_name(
kind.into(), kind.into(),
$crate::State::new::<$error_name>(Box::new(error), ), $crate::State::new::<$error_name>(error, ),
) )
} }
@ -137,7 +152,7 @@ macro_rules! error_chain_processed {
} }
/// Iterates over the error chain. /// Iterates over the error chain.
pub fn iter(&self) -> $crate::ErrorChainIter { pub fn iter(&self) -> $crate::Iter {
$crate::ChainedError::iter(self) $crate::ChainedError::iter(self)
} }
@ -145,6 +160,12 @@ macro_rules! error_chain_processed {
pub fn backtrace(&self) -> Option<&$crate::Backtrace> { pub fn backtrace(&self) -> Option<&$crate::Backtrace> {
self.1.backtrace() self.1.backtrace()
} }
/// Extends the error chain with a new entry.
pub fn chain_err<F, EK>(self, error: F) -> $error_name
where F: FnOnce() -> EK, EK: Into<$error_kind_name> {
$error_name::with_chain(self, Self::from_kind(error().into()))
}
} }
impl ::std::error::Error for $error_name { impl ::std::error::Error for $error_name {
@ -152,6 +173,7 @@ macro_rules! error_chain_processed {
self.0.description() self.0.description()
} }
#[allow(unknown_lints, unused_doc_comment)]
fn cause(&self) -> Option<&::std::error::Error> { fn cause(&self) -> Option<&::std::error::Error> {
match self.1.next_error { match self.1.next_error {
Some(ref c) => Some(&**c), Some(ref c) => Some(&**c),
@ -229,7 +251,7 @@ macro_rules! error_chain_processed {
// The ErrorKind type // The ErrorKind type
// -------------- // --------------
quick_error! { impl_error_chain_kind! {
/// The kind of an error. /// The kind of an error.
#[derive(Debug)] #[derive(Debug)]
pub enum $error_kind_name { pub enum $error_kind_name {
@ -290,7 +312,7 @@ macro_rules! error_chain_processed {
// The ResultExt trait defines the `chain_err` method. // The ResultExt trait defines the `chain_err` method.
/// Additional methods for `Result`, for easy interaction with this crate. /// Additional methods for `Result`, for easy interaction with this crate.
pub trait $result_ext_name<T, E> { pub trait $result_ext_name<T> {
/// If the `Result` is an `Err` then `chain_err` evaluates the closure, /// If the `Result` is an `Err` then `chain_err` evaluates the closure,
/// which returns *some type that can be converted to `ErrorKind`*, boxes /// which returns *some type that can be converted to `ErrorKind`*, boxes
/// the original error to store as the cause, then returns a new error /// the original error to store as the cause, then returns a new error
@ -300,7 +322,7 @@ macro_rules! error_chain_processed {
EK: Into<$error_kind_name>; EK: Into<$error_kind_name>;
} }
impl<T, E> $result_ext_name<T, E> for ::std::result::Result<T, E> where E: ::std::error::Error + Send + 'static { impl<T, E> $result_ext_name<T> for ::std::result::Result<T, E> where E: ::std::error::Error + Send + 'static {
fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name> fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
where F: FnOnce() -> EK, where F: FnOnce() -> EK,
EK: Into<$error_kind_name> { EK: Into<$error_kind_name> {
@ -311,6 +333,16 @@ macro_rules! error_chain_processed {
} }
} }
impl<T> $result_ext_name<T> for ::std::option::Option<T> {
fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
where F: FnOnce() -> EK,
EK: Into<$error_kind_name> {
self.ok_or_else(move || {
$crate::ChainedError::from_kind(callback().into())
})
}
}
}; };
} }
@ -360,7 +392,7 @@ macro_rules! error_chain_processing {
} }
}; };
( ($a:tt, $b:tt, $c:tt, $d:tt) ) => { ( ($a:tt, $b:tt, $c:tt, $d:tt) ) => {
error_chain_processed! { impl_error_chain_processed! {
types $a types $a
links $b links $b
foreign_links $c foreign_links $c
@ -369,8 +401,7 @@ macro_rules! error_chain_processing {
}; };
} }
/// This macro is used for handling of duplicated and out-of-order fields. For /// Macro for generating error types and traits. See crate level documentation for details.
/// the exact rules, see `error_chain_processed`.
#[macro_export] #[macro_export]
macro_rules! error_chain { macro_rules! error_chain {
( $( $block_name:ident { $( $block_content:tt )* } )* ) => { ( $( $block_name:ident { $( $block_content:tt )* } )* ) => {
@ -393,6 +424,7 @@ macro_rules! impl_extract_backtrace {
($error_name: ident ($error_name: ident
$error_kind_name: ident $error_kind_name: ident
$([$link_error_path: path, $(#[$meta_links: meta])*])*) => { $([$link_error_path: path, $(#[$meta_links: meta])*])*) => {
#[allow(unknown_lints, unused_doc_comment)]
fn extract_backtrace(e: &(::std::error::Error + Send + 'static)) fn extract_backtrace(e: &(::std::error::Error + Send + 'static))
-> Option<::std::sync::Arc<$crate::Backtrace>> { -> Option<::std::sync::Arc<$crate::Backtrace>> {
if let Some(e) = e.downcast_ref::<$error_name>() { if let Some(e) = e.downcast_ref::<$error_name>() {

View File

@ -21,7 +21,7 @@
/// Another code generated by the macro. /// Another code generated by the macro.
pub mod inner { pub mod inner {
error_chain! {} error_chain!{}
} }
error_chain! { error_chain! {

View File

@ -4,18 +4,19 @@
// - $imeta // - $imeta
#[macro_export] #[macro_export]
macro_rules! quick_error { #[doc(hidden)]
macro_rules! impl_error_chain_kind {
( $(#[$meta:meta])* ( $(#[$meta:meta])*
pub enum $name:ident { $($chunks:tt)* } pub enum $name:ident { $($chunks:tt)* }
) => { ) => {
quick_error!(SORT [pub enum $name $(#[$meta])* ] impl_error_chain_kind!(SORT [pub enum $name $(#[$meta])* ]
items [] buf [] items [] buf []
queue [ $($chunks)* ]); queue [ $($chunks)* ]);
}; };
( $(#[$meta:meta])* ( $(#[$meta:meta])*
enum $name:ident { $($chunks:tt)* } enum $name:ident { $($chunks:tt)* }
) => { ) => {
quick_error!(SORT [enum $name $(#[$meta])* ] impl_error_chain_kind!(SORT [enum $name $(#[$meta])* ]
items [] buf [] items [] buf []
queue [ $($chunks)* ]); queue [ $($chunks)* ]);
}; };
@ -27,16 +28,16 @@ macro_rules! quick_error {
buf [ ] buf [ ]
queue [ ] queue [ ]
) => { ) => {
quick_error!(ENUM_DEFINITION [enum $name $( #[$meta] )*] impl_error_chain_kind!(ENUM_DEFINITION [enum $name $( #[$meta] )*]
body [] body []
queue [$($( #[$imeta] )* queue [$($( #[$imeta] )*
=> $iitem: $imode [$( $ivar: $ityp ),*] )*] => $iitem: $imode [$( $ivar: $ityp ),*] )*]
); );
quick_error!(IMPLEMENTATIONS $name {$( impl_error_chain_kind!(IMPLEMENTATIONS $name {$(
$iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*} $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*}
)*}); )*});
$( $(
quick_error!(ERROR_CHECK $imode $($ifuncs)*); impl_error_chain_kind!(ERROR_CHECK $imode $($ifuncs)*);
)* )*
}; };
(SORT [pub enum $name:ident $( #[$meta:meta] )*] (SORT [pub enum $name:ident $( #[$meta:meta] )*]
@ -46,16 +47,16 @@ macro_rules! quick_error {
buf [ ] buf [ ]
queue [ ] queue [ ]
) => { ) => {
quick_error!(ENUM_DEFINITION [pub enum $name $( #[$meta] )*] impl_error_chain_kind!(ENUM_DEFINITION [pub enum $name $( #[$meta] )*]
body [] body []
queue [$($( #[$imeta] )* queue [$($( #[$imeta] )*
=> $iitem: $imode [$( $ivar: $ityp ),*] )*] => $iitem: $imode [$( $ivar: $ityp ),*] )*]
); );
quick_error!(IMPLEMENTATIONS $name {$( impl_error_chain_kind!(IMPLEMENTATIONS $name {$(
$iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*} $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*}
)*}); )*});
$( $(
quick_error!(ERROR_CHECK $imode $($ifuncs)*); impl_error_chain_kind!(ERROR_CHECK $imode $($ifuncs)*);
)* )*
}; };
// Add meta to buffer // Add meta to buffer
@ -66,7 +67,7 @@ macro_rules! quick_error {
buf [$( #[$bmeta:meta] )*] buf [$( #[$bmeta:meta] )*]
queue [ #[$qmeta:meta] $( $tail:tt )*] queue [ #[$qmeta:meta] $( $tail:tt )*]
) => { ) => {
quick_error!(SORT [$( $def )*] impl_error_chain_kind!(SORT [$( $def )*]
items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*] items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
buf [$( #[$bmeta] )* #[$qmeta] ] buf [$( #[$bmeta] )* #[$qmeta] ]
queue [$( $tail )*]); queue [$( $tail )*]);
@ -79,7 +80,7 @@ macro_rules! quick_error {
buf [$( #[$bmeta:meta] )*] buf [$( #[$bmeta:meta] )*]
queue [ $qitem:ident $( $tail:tt )*] queue [ $qitem:ident $( $tail:tt )*]
) => { ) => {
quick_error!(SORT [$( $def )*] impl_error_chain_kind!(SORT [$( $def )*]
items [$( $(#[$imeta])* items [$( $(#[$imeta])*
=> $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*] => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
buf [$(#[$bmeta])* => $qitem : UNIT [ ] ] buf [$(#[$bmeta])* => $qitem : UNIT [ ] ]
@ -94,7 +95,7 @@ macro_rules! quick_error {
=> $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ] => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
queue [ #[$qmeta:meta] $( $tail:tt )*] queue [ #[$qmeta:meta] $( $tail:tt )*]
) => { ) => {
quick_error!(SORT [$( $def )*] impl_error_chain_kind!(SORT [$( $def )*]
enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )* enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )*
$(#[$bmeta])* => $bitem: $bmode $(( $($btyp),* ))*] $(#[$bmeta])* => $bitem: $bmode $(( $($btyp),* ))*]
items [$($( #[$imeta:meta] )* items [$($( #[$imeta:meta] )*
@ -111,7 +112,7 @@ macro_rules! quick_error {
buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ] buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
queue [($( $qvar:ident: $qtyp:ty ),+) $( $tail:tt )*] queue [($( $qvar:ident: $qtyp:ty ),+) $( $tail:tt )*]
) => { ) => {
quick_error!(SORT [$( $def )*] impl_error_chain_kind!(SORT [$( $def )*]
items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*] items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
buf [$( #[$bmeta] )* => $bitem: TUPLE [$( $qvar:$qtyp ),*] ] buf [$( #[$bmeta] )* => $bitem: TUPLE [$( $qvar:$qtyp ),*] ]
queue [$( $tail )*] queue [$( $tail )*]
@ -125,7 +126,7 @@ macro_rules! quick_error {
buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ] buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
queue [{ $( $qvar:ident: $qtyp:ty ),+} $( $tail:tt )*] queue [{ $( $qvar:ident: $qtyp:ty ),+} $( $tail:tt )*]
) => { ) => {
quick_error!(SORT [$( $def )*] impl_error_chain_kind!(SORT [$( $def )*]
items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*] items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ] buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ]
queue [$( $tail )*]); queue [$( $tail )*]);
@ -138,7 +139,7 @@ macro_rules! quick_error {
buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ] buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
queue [{$( $qvar:ident: $qtyp:ty ),+ ,} $( $tail:tt )*] queue [{$( $qvar:ident: $qtyp:ty ),+ ,} $( $tail:tt )*]
) => { ) => {
quick_error!(SORT [$( $def )*] impl_error_chain_kind!(SORT [$( $def )*]
items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*] items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ] buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ]
queue [$( $tail )*]); queue [$( $tail )*]);
@ -152,7 +153,7 @@ macro_rules! quick_error {
=> $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ] => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
queue [ {$( $qfuncs:tt )*} $( $tail:tt )*] queue [ {$( $qfuncs:tt )*} $( $tail:tt )*]
) => { ) => {
quick_error!(SORT [$( $def )*] impl_error_chain_kind!(SORT [$( $def )*]
items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )* items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
$(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {$( $qfuncs )*} ] $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {$( $qfuncs )*} ]
buf [ ] buf [ ]
@ -167,7 +168,7 @@ macro_rules! quick_error {
=> $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ] => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
queue [ $qitem:ident $( $tail:tt )*] queue [ $qitem:ident $( $tail:tt )*]
) => { ) => {
quick_error!(SORT [$( $def )*] impl_error_chain_kind!(SORT [$( $def )*]
items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )* items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
$(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ] $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
buf [ => $qitem : UNIT [ ] ] buf [ => $qitem : UNIT [ ] ]
@ -182,7 +183,7 @@ macro_rules! quick_error {
=> $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ] => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
queue [ ] queue [ ]
) => { ) => {
quick_error!(SORT [$( $def )*] impl_error_chain_kind!(SORT [$( $def )*]
items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )* items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
$(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ] $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
buf [ ] buf [ ]
@ -200,6 +201,9 @@ macro_rules! quick_error {
$(#[$imeta])* $(#[$imeta])*
$iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*, $iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*,
)* )*
#[doc(hidden)]
__Nonexhaustive {}
} }
}; };
// Private enum (Queue Empty) // Private enum (Queue Empty)
@ -223,7 +227,7 @@ macro_rules! quick_error {
queue [$( #[$qmeta:meta] )* queue [$( #[$qmeta:meta] )*
=> $qitem:ident: UNIT [ ] $( $queue:tt )*] => $qitem:ident: UNIT [ ] $( $queue:tt )*]
) => { ) => {
quick_error!(ENUM_DEFINITION [ $($def)* ] impl_error_chain_kind!(ENUM_DEFINITION [ $($def)* ]
body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )* body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
$( #[$qmeta] )* => $qitem () {} ] $( #[$qmeta] )* => $qitem () {} ]
queue [ $($queue)* ] queue [ $($queue)* ]
@ -236,7 +240,7 @@ macro_rules! quick_error {
queue [$( #[$qmeta:meta] )* queue [$( #[$qmeta:meta] )*
=> $qitem:ident: TUPLE [$( $qvar:ident: $qtyp:ty ),+] $( $queue:tt )*] => $qitem:ident: TUPLE [$( $qvar:ident: $qtyp:ty ),+] $( $queue:tt )*]
) => { ) => {
quick_error!(ENUM_DEFINITION [ $($def)* ] impl_error_chain_kind!(ENUM_DEFINITION [ $($def)* ]
body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )* body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
$( #[$qmeta] )* => $qitem (($( $qtyp ),*)) {} ] $( #[$qmeta] )* => $qitem (($( $qtyp ),*)) {} ]
queue [ $($queue)* ] queue [ $($queue)* ]
@ -249,7 +253,7 @@ macro_rules! quick_error {
queue [$( #[$qmeta:meta] )* queue [$( #[$qmeta:meta] )*
=> $qitem:ident: STRUCT [$( $qvar:ident: $qtyp:ty ),*] $( $queue:tt )*] => $qitem:ident: STRUCT [$( $qvar:ident: $qtyp:ty ),*] $( $queue:tt )*]
) => { ) => {
quick_error!(ENUM_DEFINITION [ $($def)* ] impl_error_chain_kind!(ENUM_DEFINITION [ $($def)* ]
body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )* body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
$( #[$qmeta] )* => $qitem () {{$( $qvar: $qtyp ),*}} ] $( #[$qmeta] )* => $qitem () {{$( $qvar: $qtyp ),*}} ]
queue [ $($queue)* ] queue [ $($queue)* ]
@ -260,7 +264,7 @@ macro_rules! quick_error {
$item:ident: $imode:tt [$(#[$imeta:meta])*] [$( $var:ident: $typ:ty ),*] {$( $funcs:tt )*} $item:ident: $imode:tt [$(#[$imeta:meta])*] [$( $var:ident: $typ:ty ),*] {$( $funcs:tt )*}
)*} )*}
) => { ) => {
#[allow(unused)] #[allow(unknown_lints, unused, unused_doc_comment)]
impl ::std::fmt::Display for $name { impl ::std::fmt::Display for $name {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
-> ::std::fmt::Result -> ::std::fmt::Result
@ -268,16 +272,18 @@ macro_rules! quick_error {
match *self { match *self {
$( $(
$(#[$imeta])* $(#[$imeta])*
quick_error!(ITEM_PATTERN impl_error_chain_kind!(ITEM_PATTERN
$name $item: $imode [$( ref $var ),*] $name $item: $imode [$( ref $var ),*]
) => { ) => {
let display_fn = quick_error!(FIND_DISPLAY_IMPL let display_fn = impl_error_chain_kind!(FIND_DISPLAY_IMPL
$name $item: $imode $name $item: $imode
{$( $funcs )*}); {$( $funcs )*});
display_fn(self, fmt) display_fn(self, fmt)
} }
)* )*
_ => Ok(())
} }
} }
} }
@ -286,10 +292,10 @@ macro_rules! quick_error {
fn description(&self) -> &str { fn description(&self) -> &str {
match *self { match *self {
$( $(
quick_error!(ITEM_PATTERN impl_error_chain_kind!(ITEM_PATTERN
$name $item: $imode [$( ref $var ),*] $name $item: $imode [$( ref $var ),*]
) => { ) => {
quick_error!(FIND_DESCRIPTION_IMPL impl_error_chain_kind!(FIND_DESCRIPTION_IMPL
$item: $imode self fmt [$( $var ),*] $item: $imode self fmt [$( $var ),*]
{$( $funcs )*}) {$( $funcs )*})
} }
@ -299,10 +305,10 @@ macro_rules! quick_error {
fn cause(&self) -> Option<&::std::error::Error> { fn cause(&self) -> Option<&::std::error::Error> {
match *self { match *self {
$( $(
quick_error!(ITEM_PATTERN impl_error_chain_kind!(ITEM_PATTERN
$name $item: $imode [$( ref $var ),*] $name $item: $imode [$( ref $var ),*]
) => { ) => {
quick_error!(FIND_CAUSE_IMPL impl_error_chain_kind!(FIND_CAUSE_IMPL
$item: $imode [$( $var ),*] $item: $imode [$( $var ),*]
{$( $funcs )*}) {$( $funcs )*})
} }
@ -310,26 +316,28 @@ macro_rules! quick_error {
} }
} }
}*/ }*/
#[allow(unused)] #[allow(unknown_lints, unused, unused_doc_comment)]
impl $name { impl $name {
/// A string describing the error kind. /// A string describing the error kind.
pub fn description(&self) -> &str { pub fn description(&self) -> &str {
match *self { match *self {
$( $(
$(#[$imeta])* $(#[$imeta])*
quick_error!(ITEM_PATTERN impl_error_chain_kind!(ITEM_PATTERN
$name $item: $imode [$( ref $var ),*] $name $item: $imode [$( ref $var ),*]
) => { ) => {
quick_error!(FIND_DESCRIPTION_IMPL impl_error_chain_kind!(FIND_DESCRIPTION_IMPL
$item: $imode self fmt [$( $var ),*] $item: $imode self fmt [$( $var ),*]
{$( $funcs )*}) {$( $funcs )*})
} }
)* )*
_ => "",
} }
} }
} }
$( $(
quick_error!(FIND_FROM_IMPL impl_error_chain_kind!(FIND_FROM_IMPL
$name $item: $imode [$( $var:$typ ),*] $name $item: $imode [$( $var:$typ ),*]
{$( $funcs )*}); {$( $funcs )*});
)* )*
@ -337,7 +345,7 @@ macro_rules! quick_error {
(FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
{ display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*} { display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*}
) => { ) => {
|quick_error!(IDENT $self_): &$name, f: &mut ::std::fmt::Formatter| { |impl_error_chain_kind!(IDENT $self_): &$name, f: &mut ::std::fmt::Formatter| {
write!(f, $( $exprs )*) write!(f, $( $exprs )*)
} }
}; };
@ -354,7 +362,7 @@ macro_rules! quick_error {
(FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
{ $t:tt $( $tail:tt )*} { $t:tt $( $tail:tt )*}
) => { ) => {
quick_error!(FIND_DISPLAY_IMPL impl_error_chain_kind!(FIND_DISPLAY_IMPL
$name $item: $imode $name $item: $imode
{$( $tail )*}) {$( $tail )*})
}; };
@ -375,7 +383,7 @@ macro_rules! quick_error {
[$( $var:ident ),*] [$( $var:ident ),*]
{ $t:tt $( $tail:tt )*} { $t:tt $( $tail:tt )*}
) => { ) => {
quick_error!(FIND_DESCRIPTION_IMPL impl_error_chain_kind!(FIND_DESCRIPTION_IMPL
$item: $imode $me $fmt [$( $var ),*] $item: $imode $me $fmt [$( $var ),*]
{$( $tail )*}) {$( $tail )*})
}; };
@ -395,7 +403,7 @@ macro_rules! quick_error {
[$( $var:ident ),*] [$( $var:ident ),*]
{ $t:tt $( $tail:tt )*} { $t:tt $( $tail:tt )*}
) => { ) => {
quick_error!(FIND_CAUSE_IMPL impl_error_chain_kind!(FIND_CAUSE_IMPL
$item: $imode [$( $var ),*] $item: $imode [$( $var ),*]
{ $($tail)* }) { $($tail)* })
}; };
@ -416,7 +424,7 @@ macro_rules! quick_error {
} }
} }
)* )*
quick_error!(FIND_FROM_IMPL impl_error_chain_kind!(FIND_FROM_IMPL
$name $item: $imode [$( $var:$typ ),*] $name $item: $imode [$( $var:$typ ),*]
{$( $tail )*}); {$( $tail )*});
}; };
@ -429,7 +437,7 @@ macro_rules! quick_error {
$name::$item $name::$item
} }
} }
quick_error!(FIND_FROM_IMPL impl_error_chain_kind!(FIND_FROM_IMPL
$name $item: UNIT [ ] $name $item: UNIT [ ]
{$( $tail )*}); {$( $tail )*});
}; };
@ -442,7 +450,7 @@ macro_rules! quick_error {
$name::$item($( $texpr ),*) $name::$item($( $texpr ),*)
} }
} }
quick_error!(FIND_FROM_IMPL impl_error_chain_kind!(FIND_FROM_IMPL
$name $item: TUPLE [$( $var:$typ ),*] $name $item: TUPLE [$( $var:$typ ),*]
{ $($tail)* }); { $($tail)* });
}; };
@ -457,7 +465,7 @@ macro_rules! quick_error {
} }
} }
} }
quick_error!(FIND_FROM_IMPL impl_error_chain_kind!(FIND_FROM_IMPL
$name $item: STRUCT [$( $var:$typ ),*] $name $item: STRUCT [$( $var:$typ ),*]
{ $($tail)* }); { $($tail)* });
}; };
@ -465,7 +473,7 @@ macro_rules! quick_error {
[$( $var:ident: $typ:ty ),*] [$( $var:ident: $typ:ty ),*]
{ $t:tt $( $tail:tt )*} { $t:tt $( $tail:tt )*}
) => { ) => {
quick_error!(FIND_FROM_IMPL impl_error_chain_kind!(FIND_FROM_IMPL
$name $item: $imode [$( $var:$typ ),*] $name $item: $imode [$( $var:$typ ),*]
{$( $tail )*} {$( $tail )*}
); );
@ -506,24 +514,28 @@ macro_rules! quick_error {
// This is to contrast FIND_* clauses which just find stuff they need and // This is to contrast FIND_* clauses which just find stuff they need and
// skip everything else completely // skip everything else completely
(ERROR_CHECK $imode:tt display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*) (ERROR_CHECK $imode:tt display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*)
=> { quick_error!(ERROR_CHECK $imode $($tail)*); }; => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
(ERROR_CHECK $imode:tt display($pattern: expr) $( $tail:tt )*) (ERROR_CHECK $imode:tt display($pattern: expr) $( $tail:tt )*)
=> { quick_error!(ERROR_CHECK $imode $($tail)*); }; => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
(ERROR_CHECK $imode:tt display($pattern: expr, $( $exprs:tt )*) $( $tail:tt )*) (ERROR_CHECK $imode:tt display($pattern: expr, $( $exprs:tt )*) $( $tail:tt )*)
=> { quick_error!(ERROR_CHECK $imode $($tail)*); }; => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
(ERROR_CHECK $imode:tt description($expr:expr) $( $tail:tt )*) (ERROR_CHECK $imode:tt description($expr:expr) $( $tail:tt )*)
=> { quick_error!(ERROR_CHECK $imode $($tail)*); }; => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
(ERROR_CHECK $imode:tt cause($expr:expr) $($tail:tt)*) (ERROR_CHECK $imode:tt cause($expr:expr) $($tail:tt)*)
=> { quick_error!(ERROR_CHECK $imode $($tail)*); }; => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
(ERROR_CHECK $imode:tt from() $($tail:tt)*) (ERROR_CHECK $imode:tt from() $($tail:tt)*)
=> { quick_error!(ERROR_CHECK $imode $($tail)*); }; => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
(ERROR_CHECK $imode:tt from($ftyp:ty) $($tail:tt)*) (ERROR_CHECK $imode:tt from($ftyp:ty) $($tail:tt)*)
=> { quick_error!(ERROR_CHECK $imode $($tail)*); }; => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
(ERROR_CHECK TUPLE from($fvar:ident: $ftyp:ty) -> ($( $e:expr ),*) $( $tail:tt )*) (ERROR_CHECK TUPLE from($fvar:ident: $ftyp:ty) -> ($( $e:expr ),*) $( $tail:tt )*)
=> { quick_error!(ERROR_CHECK TUPLE $($tail)*); }; => { impl_error_chain_kind!(ERROR_CHECK_COMMA TUPLE $($tail)*); };
(ERROR_CHECK STRUCT from($fvar:ident: $ftyp:ty) -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*) (ERROR_CHECK STRUCT from($fvar:ident: $ftyp:ty) -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*)
=> { quick_error!(ERROR_CHECK STRUCT $($tail)*); }; => { impl_error_chain_kind!(ERROR_CHECK_COMMA STRUCT $($tail)*); };
(ERROR_CHECK $imode:tt ) => {}; (ERROR_CHECK $imode:tt ) => {};
(ERROR_CHECK_COMMA $imode:tt , $( $tail:tt )*)
=> { impl_error_chain_kind!(ERROR_CHECK $imode $($tail)*); };
(ERROR_CHECK_COMMA $imode:tt $( $tail:tt )*)
=> { impl_error_chain_kind!(ERROR_CHECK $imode $($tail)*); };
// Utility functions // Utility functions
(IDENT $ident:ident) => { $ident } (IDENT $ident:ident) => { $ident }
} }

View File

@ -1,4 +1,6 @@
#![deny(missing_docs)] #![deny(missing_docs)]
#![allow(unknown_lints)] // to be removed when unused_doc_comments lints is merged
#![doc(html_root_url = "https://docs.rs/error-chain/0.11.0")]
//! A library for consistent and reliable error handling //! A library for consistent and reliable error handling
//! //!
@ -14,7 +16,7 @@
//! follow the [quickstart.rs] template, and read this [intro] //! follow the [quickstart.rs] template, and read this [intro]
//! to error-chain. //! to error-chain.
//! //!
//! [quickstart.rs]: https://github.com/brson/error-chain/blob/master/examples/quickstart.rs //! [quickstart.rs]: https://github.com/rust-lang-nursery/error-chain/blob/master/examples/quickstart.rs
//! [intro]: http://brson.github.io/2016/11/30/starting-with-error-chain //! [intro]: http://brson.github.io/2016/11/30/starting-with-error-chain
//! //!
//! ## Why error chain? //! ## Why error chain?
@ -22,7 +24,7 @@
//! * error-chain is easy to configure. Handle errors robustly with minimal //! * error-chain is easy to configure. Handle errors robustly with minimal
//! effort. //! effort.
//! * Basic error handling requires no maintenance of custom error types //! * Basic error handling requires no maintenance of custom error types
//! nor the `From` conversions that make `?` work. //! nor the [`From`] conversions that make `?` work.
//! * error-chain scales from simple error handling strategies to more //! * error-chain scales from simple error handling strategies to more
//! rigorous. Return formatted strings for simple errors, only //! rigorous. Return formatted strings for simple errors, only
//! introducing error variants and their strong typing as needed for //! introducing error variants and their strong typing as needed for
@ -38,56 +40,56 @@
//! error-chain is based on the following principles: //! error-chain is based on the following principles:
//! //!
//! * No error should ever be discarded. This library primarily //! * No error should ever be discarded. This library primarily
//! makes it easy to "chain" errors with the `chain_err` method. //! makes it easy to "chain" errors with the [`chain_err`] method.
//! * Introducing new errors is trivial. Simple errors can be introduced //! * Introducing new errors is trivial. Simple errors can be introduced
//! at the error site with just a string. //! at the error site with just a string.
//! * Handling errors is possible with pattern matching. //! * Handling errors is possible with pattern matching.
//! * Conversions between error types are done in an automatic and //! * Conversions between error types are done in an automatic and
//! consistent way - `From` conversion behavior is never specified //! consistent way - [`From`] conversion behavior is never specified
//! explicitly. //! explicitly.
//! * Errors implement Send. //! * Errors implement [`Send`].
//! * Errors can carry backtraces. //! * Errors can carry backtraces.
//! //!
//! Similar to other libraries like [error-type] and [quick-error], //! Similar to other libraries like [error-type] and [quick-error],
//! this library introduces the error chaining mechanism originally //! this library introduces the error chaining mechanism originally
//! employed by Cargo. The `error_chain!` macro declares the types //! employed by Cargo. The [`error_chain!`] macro declares the types
//! and implementation boilerplate necessary for fulfilling a //! and implementation boilerplate necessary for fulfilling a
//! particular error-handling strategy. Most importantly it defines a //! particular error-handling strategy. Most importantly it defines a
//! custom error type (called `Error` by convention) and the `From` //! custom error type (called [`Error`] by convention) and the [`From`]
//! conversions that let the `try!` macro and `?` operator work. //! conversions that let the `?` operator work.
//! //!
//! This library differs in a few ways from previous error libs: //! This library differs in a few ways from previous error libs:
//! //!
//! * Instead of defining the custom `Error` type as an enum, it is a //! * Instead of defining the custom [`Error`] type as an enum, it is a
//! struct containing an `ErrorKind` (which defines the //! struct containing an [`ErrorKind`][] (which defines the
//! `description` and `display` methods for the error), an opaque, //! [`description`] and [`display_chain`] methods for the error), an opaque,
//! optional, boxed `std::error::Error + Send + 'static` object //! optional, boxed [`std::error::Error`]` + `[`Send`]` + 'static` object
//! (which defines the `cause`, and establishes the links in the //! (which defines the [`cause`], and establishes the links in the
//! error chain), and a `Backtrace`. //! error chain), and a [`Backtrace`].
//! * The macro also defines a `ResultExt` trait that defines a //! * The macro also defines a [`ResultExt`] trait that defines a
//! `chain_err` method. This method on all `std::error::Error + Send + 'static` //! [`chain_err`] method. This method on all [`std::error::Error`]` + `[`Send`]` + 'static`
//! types extends the error chain by boxing the current //! types extends the error chain by boxing the current
//! error into an opaque object and putting it inside a new concrete //! error into an opaque object and putting it inside a new concrete
//! error. //! error.
//! * It provides automatic `From` conversions between other error types //! * It provides automatic [`From`] conversions between other error types
//! defined by the `error_chain!` that preserve type information, //! defined by the [`error_chain!`] that preserve type information,
//! and facilitate seamless error composition and matching of composed //! and facilitate seamless error composition and matching of composed
//! errors. //! errors.
//! * It provides automatic `From` conversions between any other error //! * It provides automatic [`From`] conversions between any other error
//! type that hides the type of the other error in the `cause` box. //! type that hides the type of the other error in the [`cause`] box.
//! * If `RUST_BACKTRACE` is enabled, it collects a single backtrace at //! * If `RUST_BACKTRACE` is enabled, it collects a single backtrace at
//! the earliest opportunity and propagates it down the stack through //! the earliest opportunity and propagates it down the stack through
//! `From` and `ResultExt` conversions. //! [`From`] and [`ResultExt`] conversions.
//! //!
//! To accomplish its goals it makes some tradeoffs: //! To accomplish its goals it makes some tradeoffs:
//! //!
//! * The split between the `Error` and `ErrorKind` types can make it //! * The split between the [`Error`] and [`ErrorKind`] types can make it
//! slightly more cumbersome to instantiate new (unchained) errors, //! slightly more cumbersome to instantiate new (unchained) errors,
//! requiring an `Into` or `From` conversion; as well as slightly //! requiring an [`Into`] or [`From`] conversion; as well as slightly
//! more cumbersome to match on errors with another layer of types //! more cumbersome to match on errors with another layer of types
//! to match. //! to match.
//! * Because the error type contains `std::error::Error + Send + 'static` objects, //! * Because the error type contains [`std::error::Error`]` + `[`Send`]` + 'static` objects,
//! it can't implement `PartialEq` for easy comparisons. //! it can't implement [`PartialEq`] for easy comparisons.
//! //!
//! ## Declaring error types //! ## Declaring error types
//! //!
@ -96,7 +98,7 @@
//! basis, such as per module. //! basis, such as per module.
//! //!
//! Assuming you are using crate-level error types, typically you will //! Assuming you are using crate-level error types, typically you will
//! define an `errors` module and inside it call `error_chain!`: //! define an `errors` module and inside it call [`error_chain!`]:
//! //!
//! ``` //! ```
//! # #[macro_use] extern crate error_chain; //! # #[macro_use] extern crate error_chain;
@ -147,14 +149,20 @@
//! Io(::std::io::Error) #[cfg(unix)]; //! Io(::std::io::Error) #[cfg(unix)];
//! } //! }
//! //!
//! // Define additional `ErrorKind` variants. The syntax here is //! // Define additional `ErrorKind` variants. Define custom responses with the
//! // the same as `quick_error!`, but the `from()` and `cause()` //! // `description` and `display` calls.
//! // syntax is not supported.
//! errors { //! errors {
//! InvalidToolchainName(t: String) { //! InvalidToolchainName(t: String) {
//! description("invalid toolchain name") //! description("invalid toolchain name")
//! display("invalid toolchain name: '{}'", t) //! display("invalid toolchain name: '{}'", t)
//! } //! }
//!
//! // You can also add commas after description/display.
//! // This may work better with some editor auto-indentation modes:
//! UnknownToolchainVersion(v: String) {
//! description("unknown toolchain version"), // note the ,
//! display("unknown toolchain version: '{}'", v), // trailing comma is allowed
//! }
//! } //! }
//! } //! }
//! //!
@ -165,9 +173,9 @@
//! be omitted if it is empty. //! be omitted if it is empty.
//! //!
//! This populates the module with a number of definitions, //! This populates the module with a number of definitions,
//! the most important of which are the `Error` type //! the most important of which are the [`Error`] type
//! and the `ErrorKind` type. An example of generated code can be found in the //! and the [`ErrorKind`] type. An example of generated code can be found in the
//! [example_generated](example_generated) module. //! [example_generated](example_generated/index.html) module.
//! //!
//! ## Returning new errors //! ## Returning new errors
//! //!
@ -182,7 +190,7 @@
//! } //! }
//! ``` //! ```
//! //!
//! Introducing new error chains, with an `ErrorKind`: //! Introducing new error chains, with an [`ErrorKind`]:
//! //!
//! ``` //! ```
//! # #[macro_use] extern crate error_chain; //! # #[macro_use] extern crate error_chain;
@ -196,37 +204,37 @@
//! } //! }
//! ``` //! ```
//! //!
//! Note that the return type is the typedef `Result`, which is //! Note that the return type is the typedef [`Result`], which is
//! defined by the macro as `pub type Result<T> = //! defined by the macro as `pub type Result<T> =
//! ::std::result::Result<T, Error>`. Note that in both cases //! ::std::result::Result<T, Error>`. Note that in both cases
//! `.into()` is called to convert a type into the `Error` type; both //! [`.into()`] is called to convert a type into the [`Error`] type; both
//! strings and `ErrorKind` have `From` conversions to turn them into //! strings and [`ErrorKind`] have [`From`] conversions to turn them into
//! `Error`. //! [`Error`].
//! //!
//! When the error is emitted inside a `try!` macro or behind the //! When the error is emitted behind the `?` operator, the explicit conversion
//! `?` operator, the explicit conversion isn't needed; `try!` will //! isn't needed; `Err(ErrorKind)` will automatically be converted to `Err(Error)`.
//! automatically convert `Err(ErrorKind)` to `Err(Error)`. So the //! So the below is equivalent to the previous:
//! below is equivalent to the previous:
//! //!
//! ``` //! ```
//! # #[macro_use] extern crate error_chain; //! # #[macro_use] extern crate error_chain;
//! # fn main() {} //! # fn main() {}
//! # error_chain! { errors { FooError } } //! # error_chain! { errors { FooError } }
//! fn foo() -> Result<()> { //! fn foo() -> Result<()> {
//! Ok(try!(Err(ErrorKind::FooError))) //! Ok(Err(ErrorKind::FooError)?)
//! } //! }
//! //!
//! fn bar() -> Result<()> { //! fn bar() -> Result<()> {
//! Ok(try!(Err("bogus!"))) //! Ok(Err("bogus!")?)
//! } //! }
//! ``` //! ```
//! //!
//! ## The `bail!` macro //! ## The `bail!` macro
//! //!
//! The above method of introducing new errors works but is a little //! The above method of introducing new errors works but is a little
//! verbose. Instead we can use the `bail!` macro, which, much like `try!` //! verbose. Instead, we can use the [`bail!`] macro, which performs an early return
//! and `?`, performs an early return with conversions. With `bail!` the //! with conversions done automatically.
//! previous examples look like: //!
//! With [`bail!`] the previous examples look like:
//! //!
//! ``` //! ```
//! # #[macro_use] extern crate error_chain; //! # #[macro_use] extern crate error_chain;
@ -250,6 +258,8 @@
//! ``` //! ```
//! //!
//! ## Chaining errors //! ## Chaining errors
//! error-chain supports extending an error chain by appending new errors.
//! This can be done on a Result or on an existing Error.
//! //!
//! To extend the error chain: //! To extend the error chain:
//! //!
@ -264,17 +274,63 @@
//! # } //! # }
//! ``` //! ```
//! //!
//! `chain_err` can be called on any `Result` type where the contained //! [`chain_err`] can be called on any [`Result`] type where the contained
//! error type implements `std::error::Error + Send + 'static`. If //! error type implements [`std::error::Error`]` + `[`Send`]` + 'static`, as long as
//! the `Result` is an `Err` then `chain_err` evaluates the closure, //! the [`Result`] type's corresponding [`ResultExt`] trait is in scope. If
//! which returns *some type that can be converted to `ErrorKind`*, //! the [`Result`] is an `Err` then [`chain_err`] evaluates the closure,
//! which returns *some type that can be converted to [`ErrorKind`]*,
//! boxes the original error to store as the cause, then returns a new //! boxes the original error to store as the cause, then returns a new
//! error containing the original error. //! error containing the original error.
//! //!
//! Calling [`chain_err`][Error_chain_err] on an existing [`Error`] instance has
//! the same signature and produces the same outcome as being called on a
//! [`Result`] matching the properties described above. This is most useful when
//! partially handling errors using the [`map_err`] function.
//!
//! To chain an error directly, use [`with_chain`]:
//!
//! ```
//! # #[macro_use] extern crate error_chain;
//! # fn main() {}
//! # error_chain! {}
//! # fn do_something() -> Result<()> { unimplemented!() }
//! # fn test() -> Result<()> {
//! let res: Result<()> =
//! do_something().map_err(|e| Error::with_chain(e, "something went wrong"));
//! # Ok(())
//! # }
//! ```
//!
//! ## Linking errors
//!
//! To convert an error from another error chain to this error chain:
//!
//! ```
//! # #[macro_use] extern crate error_chain;
//! # fn main() {}
//! # mod other { error_chain! {} }
//! error_chain! {
//! links {
//! OtherError(other::Error, other::ErrorKind);
//! }
//! }
//!
//! fn do_other_thing() -> other::Result<()> { unimplemented!() }
//!
//! # fn test() -> Result<()> {
//! let res: Result<()> = do_other_thing().map_err(|e| e.into());
//! # Ok(())
//! # }
//! ```
//!
//! The [`Error`] and [`ErrorKind`] types implements [`From`] for the corresponding
//! types of all linked error chains. Linked errors do not introduce a new
//! cause to the error chain.
//!
//! ## Matching errors //! ## Matching errors
//! //!
//! error-chain error variants are matched with simple patterns. //! error-chain error variants are matched with simple patterns.
//! `Error` is a tuple struct and its first field is the `ErrorKind`, //! [`Error`] is a tuple struct and its first field is the [`ErrorKind`],
//! making dispatching on error kinds relatively compact: //! making dispatching on error kinds relatively compact:
//! //!
//! ``` //! ```
@ -292,6 +348,7 @@
//! match Error::from("error!") { //! match Error::from("error!") {
//! Error(ErrorKind::InvalidToolchainName(_), _) => { } //! Error(ErrorKind::InvalidToolchainName(_), _) => { }
//! Error(ErrorKind::Msg(_), _) => { } //! Error(ErrorKind::Msg(_), _) => { }
//! _ => { }
//! } //! }
//! # } //! # }
//! ``` //! ```
@ -327,22 +384,69 @@
//! # } //! # }
//! ``` //! ```
//! //!
//! ## Inspecting errors
//!
//! An error-chain error contains information about the error itself, a backtrace, and the chain
//! of causing errors. For reporting purposes, this information can be accessed as follows.
//!
//! ```
//! # #[macro_use] extern crate error_chain;
//! use error_chain::ChainedError; // for e.display_chain()
//!
//! error_chain! {
//! errors {
//! InvalidToolchainName(t: String) {
//! description("invalid toolchain name")
//! display("invalid toolchain name: '{}'", t)
//! }
//! }
//! }
//!
//! # fn main() {
//! // Generate an example error to inspect:
//! let e = "xyzzy".parse::<i32>()
//! .chain_err(|| ErrorKind::InvalidToolchainName("xyzzy".to_string()))
//! .unwrap_err();
//!
//! // Get the brief description of the error:
//! assert_eq!(e.description(), "invalid toolchain name");
//!
//! // Get the display version of the error:
//! assert_eq!(e.to_string(), "invalid toolchain name: 'xyzzy'");
//!
//! // Get the full cause and backtrace:
//! println!("{}", e.display_chain().to_string());
//! // Error: invalid toolchain name: 'xyzzy'
//! // Caused by: invalid digit found in string
//! // stack backtrace:
//! // 0: 0x7fa9f684fc94 - backtrace::backtrace::libunwind::trace
//! // at src/backtrace/libunwind.rs:53
//! // - backtrace::backtrace::trace<closure>
//! // at src/backtrace/mod.rs:42
//! // 1: 0x7fa9f6850b0e - backtrace::capture::{{impl}}::new
//! // at out/capture.rs:79
//! // [..]
//! # }
//! ```
//!
//! The [`Error`] and [`ErrorKind`] types also allow programmatic access to these elements.
//!
//! ## Foreign links //! ## Foreign links
//! //!
//! Errors that do not conform to the same conventions as this library //! Errors that do not conform to the same conventions as this library
//! can still be included in the error chain. They are considered "foreign //! can still be included in the error chain. They are considered "foreign
//! errors", and are declared using the `foreign_links` block of the //! errors", and are declared using the `foreign_links` block of the
//! `error_chain!` macro. `Error`s are automatically created from //! [`error_chain!`] macro. [`Error`]s are automatically created from
//! foreign errors by the `try!` macro. //! foreign errors by the `?` operator.
//! //!
//! Foreign links and regular links have one crucial difference: //! Foreign links and regular links have one crucial difference:
//! `From` conversions for regular links *do not introduce a new error //! [`From`] conversions for regular links *do not introduce a new error
//! into the error chain*, while conversions for foreign links *always //! into the error chain*, while conversions for foreign links *always
//! introduce a new error into the error chain*. So for the example //! introduce a new error into the error chain*. So for the example
//! above all errors deriving from the `temp::Error` type will be //! above all errors deriving from the [`std::fmt::Error`] type will be
//! presented to the user as a new `ErrorKind::Temp` variant, and the //! presented to the user as a new [`ErrorKind`] variant, and the
//! cause will be the original `temp::Error` error. In contrast, when //! cause will be the original [`std::fmt::Error`] error. In contrast, when
//! `rustup_utils::Error` is converted to `Error` the two `ErrorKind`s //! `other_error::Error` is converted to `Error` the two `ErrorKind`s
//! are converted between each other to create a new `Error` but the //! are converted between each other to create a new `Error` but the
//! old error is discarded; there is no "cause" created from the //! old error is discarded; there is no "cause" created from the
//! original error. //! original error.
@ -351,19 +455,87 @@
//! //!
//! If the `RUST_BACKTRACE` environment variable is set to anything //! If the `RUST_BACKTRACE` environment variable is set to anything
//! but ``0``, the earliest non-foreign error to be generated creates //! but ``0``, the earliest non-foreign error to be generated creates
//! a single backtrace, which is passed through all `From` conversions //! a single backtrace, which is passed through all [`From`] conversions
//! and `chain_err` invocations of compatible types. To read the //! and [`chain_err`] invocations of compatible types. To read the
//! backtrace just call the `backtrace()` method. //! backtrace just call the [`backtrace`] method.
//! //!
//! Backtrace generation can be disabled by turning off the `backtrace` feature. //! Backtrace generation can be disabled by turning off the `backtrace` feature.
//! //!
//! The Backtrace contains a Vec of [`BacktraceFrame`]s that can be operated
//! on directly. For example, to only see the files and line numbers of code
//! within your own project.
//!
//! ```
//! # #[macro_use]
//! # extern crate error_chain;
//! # mod errors {
//! # error_chain! {
//! # foreign_links {
//! # Io(::std::io::Error);
//! # }
//! # }
//! # }
//! # use errors::*;
//! # #[cfg(feature="backtrace")]
//! # fn main() {
//! if let Err(ref e) = open_file() {
//! if let Some(backtrace) = e.backtrace() {
//! let frames = backtrace.frames();
//! for frame in frames.iter() {
//! for symbol in frame.symbols().iter() {
//! if let (Some(file), Some(lineno)) = (symbol.filename(), symbol.lineno()) {
//! if file.display().to_string()[0..3] == "src".to_string(){
//! println!("{}:{}", file.display().to_string(), lineno);
//! }
//! }
//! }
//! }
//! }
//! };
//! # }
//! # #[cfg(not(feature="backtrace"))]
//! # fn main() { }
//!
//! fn open_file() -> Result<()> {
//! std::fs::File::open("does_not_exist")?;
//! Ok(())
//! }
//! ```
//!
//! ## Iteration //! ## Iteration
//! //!
//! The `iter` method returns an iterator over the chain of error boxes. //! The [`iter`] method returns an iterator over the chain of error boxes.
//! //!
//! [error-type]: https://github.com/DanielKeep/rust-error-type //! [error-type]: https://github.com/DanielKeep/rust-error-type
//! [quick-error]: https://github.com/tailhook/quick-error //! [quick-error]: https://github.com/tailhook/quick-error
//! [`display_chain`]: trait.ChainedError.html#method.display_chain
//! [`error_chain!`]: macro.error_chain.html
//! [`bail!`]: macro.bail.html
//! [`Backtrace`]: struct.Backtrace.html
//! [`Error`]: example_generated/struct.Error.html
//! [`with_chain`]: example_generated/struct.Error.html#method.with_chain
//! [Error_chain_err]: example_generated/struct.Error.html#method.chain_err
//! [`cause`]: example_generated/struct.Error.html#method.cause
//! [`backtrace`]: example_generated/struct.Error.html#method.backtrace
//! [`iter`]: example_generated/struct.Error.html#method.iter
//! [`ErrorKind`]: example_generated/enum.ErrorKind.html
//! [`description`]: example_generated/enum.ErrorKind.html#method.description
//! [`Result`]: example_generated/type.Result.html
//! [`ResultExt`]: example_generated/trait.ResultExt.html
//! [`chain_err`]: example_generated/trait.ResultExt.html#tymethod.chain_err
//! [`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html
//! [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
//! [`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html
//! [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
//! [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
//! [`std::fmt::Error`]: https://doc.rust-lang.org/std/fmt/struct.Error.html
//! [`.into()`]: https://doc.rust-lang.org/std/convert/trait.Into.html#tymethod.into
//! [`map_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err
//! [`BacktraceFrame`]: https://docs.rs/backtrace/0.3.2/backtrace/struct.BacktraceFrame.html
#[cfg(feature = "backtrace")] #[cfg(feature = "backtrace")]
extern crate backtrace; extern crate backtrace;
@ -381,7 +553,7 @@ pub use backtrace::Backtrace;
pub type Backtrace = (); pub type Backtrace = ();
#[macro_use] #[macro_use]
mod quick_error; mod impl_error_chain_kind;
#[macro_use] #[macro_use]
mod error_chain; mod error_chain;
#[macro_use] #[macro_use]
@ -390,10 +562,18 @@ pub use quick_main::ExitCode;
#[cfg(feature = "example_generated")] #[cfg(feature = "example_generated")]
pub mod example_generated; pub mod example_generated;
#[derive(Debug)]
/// Iterator over the error chain using the `Error::cause()` method. /// Iterator over the error chain using the `Error::cause()` method.
pub struct ErrorChainIter<'a>(pub Option<&'a error::Error>); pub struct Iter<'a>(Option<&'a error::Error>);
impl<'a> Iterator for ErrorChainIter<'a> { impl<'a> Iter<'a> {
/// Returns a new iterator over the error chain using `Error::cause()`.
pub fn new(err: Option<&'a error::Error>) -> Iter<'a> {
Iter(err)
}
}
impl<'a> Iterator for Iter<'a> {
type Item = &'a error::Error; type Item = &'a error::Error;
fn next<'b>(&'b mut self) -> Option<&'a error::Error> { fn next<'b>(&'b mut self) -> Option<&'a error::Error> {
@ -413,9 +593,29 @@ impl<'a> Iterator for ErrorChainIter<'a> {
#[cfg(feature = "backtrace")] #[cfg(feature = "backtrace")]
#[doc(hidden)] #[doc(hidden)]
pub fn make_backtrace() -> Option<Arc<Backtrace>> { pub fn make_backtrace() -> Option<Arc<Backtrace>> {
match std::env::var_os("RUST_BACKTRACE") { use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
Some(ref val) if val != "0" => Some(Arc::new(Backtrace::new())),
_ => None, // The lowest bit indicates whether the value was computed,
// while the second lowest bit is the actual "enabled" bit.
static BACKTRACE_ENABLED_CACHE: AtomicUsize = ATOMIC_USIZE_INIT;
let enabled = match BACKTRACE_ENABLED_CACHE.load(Ordering::Relaxed) {
0 => {
let enabled = match std::env::var_os("RUST_BACKTRACE") {
Some(ref val) if val != "0" => true,
_ => false
};
let encoded = ((enabled as usize) << 1) | 1;
BACKTRACE_ENABLED_CACHE.store(encoded, Ordering::Relaxed);
enabled
}
encoded => (encoded >> 1) != 0
};
if enabled {
Some(Arc::new(Backtrace::new()))
} else {
None
} }
} }
@ -438,7 +638,7 @@ pub trait ChainedError: error::Error + Send + 'static {
fn kind(&self) -> &Self::ErrorKind; fn kind(&self) -> &Self::ErrorKind;
/// Iterates over the error chain. /// Iterates over the error chain.
fn iter(&self) -> ErrorChainIter; fn iter(&self) -> Iter;
/// Returns the backtrace associated with this error. /// Returns the backtrace associated with this error.
fn backtrace(&self) -> Option<&Backtrace>; fn backtrace(&self) -> Option<&Backtrace>;
@ -447,10 +647,15 @@ pub trait ChainedError: error::Error + Send + 'static {
/// context of this error. /// context of this error.
/// ///
/// The full cause chain and backtrace, if present, will be printed. /// The full cause chain and backtrace, if present, will be printed.
fn display<'a>(&'a self) -> Display<'a, Self> { fn display_chain<'a>(&'a self) -> DisplayChain<'a, Self> {
Display(self) DisplayChain(self)
} }
/// Extends the error chain with a new entry.
fn chain_err<F, EK>(self, error: F) -> Self
where F: FnOnce() -> EK,
EK: Into<Self::ErrorKind>;
/// Creates an error from its parts. /// Creates an error from its parts.
#[doc(hidden)] #[doc(hidden)]
fn new(kind: Self::ErrorKind, state: State) -> Self where Self: Sized; fn new(kind: Self::ErrorKind, state: State) -> Self where Self: Sized;
@ -465,12 +670,13 @@ pub trait ChainedError: error::Error + Send + 'static {
/// A struct which formats an error for output. /// A struct which formats an error for output.
#[derive(Debug)] #[derive(Debug)]
pub struct Display<'a, T: 'a + ?Sized>(&'a T); pub struct DisplayChain<'a, T: 'a + ?Sized>(&'a T);
impl<'a, T> fmt::Display for Display<'a, T> impl<'a, T> fmt::Display for DisplayChain<'a, T>
where T: ChainedError where T: ChainedError
{ {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
// Keep `try!` for 1.10 support
try!(writeln!(fmt, "Error: {}", self.0)); try!(writeln!(fmt, "Error: {}", self.0));
for e in self.0.iter().skip(1) { for e in self.0.iter().skip(1) {

View File

@ -1,4 +1,4 @@
/// Convenient wrapper to be able to use `try!` and such in the main. You can /// Convenient wrapper to be able to use `?` and such in the main. You can
/// use it with a separated function: /// use it with a separated function:
/// ///
/// ``` /// ```
@ -47,7 +47,7 @@ macro_rules! quick_main {
::std::process::exit(match $main() { ::std::process::exit(match $main() {
Ok(ret) => $crate::ExitCode::code(ret), Ok(ret) => $crate::ExitCode::code(ret),
Err(ref e) => { Err(ref e) => {
write!(&mut ::std::io::stderr(), "{}", $crate::ChainedError::display(e)) write!(&mut ::std::io::stderr(), "{}", $crate::ChainedError::display_chain(e))
.expect("Error writing to stderr"); .expect("Error writing to stderr");
1 1
@ -65,9 +65,13 @@ pub trait ExitCode {
} }
impl ExitCode for i32 { impl ExitCode for i32 {
fn code(self) -> i32 { self } fn code(self) -> i32 {
self
}
} }
impl ExitCode for () { impl ExitCode for () {
fn code(self) -> i32 { 0 } fn code(self) -> i32 {
0
}
} }

View File

@ -24,7 +24,5 @@ mod i32 {
mod closure { mod closure {
use super::*; use super::*;
quick_main!(|| -> Result<()> { quick_main!(|| -> Result<()> { Ok(()) });
Ok(())
});
} }

View File

@ -1,7 +1,4 @@
#![allow(dead_code)] #![allow(dead_code)]
//#![feature(trace_macros)]
//
//trace_macros!(true);
#[macro_use] #[macro_use]
extern crate error_chain; extern crate error_chain;
@ -197,41 +194,35 @@ fn order_test_8() {
#[test] #[test]
fn empty() { fn empty() {
error_chain! { }; error_chain!{};
} }
#[test] #[test]
#[cfg(feature = "backtrace")] #[cfg(feature = "backtrace")]
fn has_backtrace_depending_on_env() { fn has_backtrace_depending_on_env() {
use std::env; use std::process::Command;
use std::path::Path;
error_chain! { let cmd_path = if cfg!(windows) {
types {} Path::new("./target/debug/has_backtrace.exe")
links {} } else {
foreign_links {} Path::new("./target/debug/has_backtrace")
errors { };
MyError let mut cmd = Command::new(cmd_path);
}
}
let original_value = env::var_os("RUST_BACKTRACE");
// missing RUST_BACKTRACE and RUST_BACKTRACE=0 // missing RUST_BACKTRACE and RUST_BACKTRACE=0
env::remove_var("RUST_BACKTRACE"); cmd.env_remove("RUST_BACKTRACE");
let err = Error::from(ErrorKind::MyError); assert_eq!(cmd.status().unwrap().code().unwrap(), 0);
assert!(err.backtrace().is_none());
env::set_var("RUST_BACKTRACE", "0"); cmd.env("RUST_BACKTRACE", "0");
let err = Error::from(ErrorKind::MyError); assert_eq!(cmd.status().unwrap().code().unwrap(), 0);
assert!(err.backtrace().is_none());
// RUST_BACKTRACE set to anything but 0 // RUST_BACKTRACE set to anything but 0
env::set_var("RUST_BACKTRACE", "yes"); cmd.env("RUST_BACKTRACE", "yes");
let err = Error::from(ErrorKind::MyError); assert_eq!(cmd.status().unwrap().code().unwrap(), 1);
assert!(err.backtrace().is_some());
if let Some(var) = original_value { cmd.env("RUST_BACKTRACE", "1");
env::set_var("RUST_BACKTRACE", var); assert_eq!(cmd.status().unwrap().code().unwrap(), 1);
}
} }
#[test] #[test]
@ -251,10 +242,30 @@ fn chain_err() {
let _: Result<()> = Err(Error::from_kind(ErrorKind::Test)).chain_err(|| ""); let _: Result<()> = Err(Error::from_kind(ErrorKind::Test)).chain_err(|| "");
} }
/// Verify that an error chain is extended one by `Error::chain_err`, with
/// the new error added to the end.
#[test]
fn error_chain_err() {
error_chain! {
errors {
Test
}
}
let base = Error::from(ErrorKind::Test);
let ext = base.chain_err(|| "Test passes");
if let Error(ErrorKind::Msg(_), _) = ext {
// pass
} else {
panic!("The error should be wrapped. {:?}", ext);
}
}
#[test] #[test]
fn links() { fn links() {
mod test { mod test {
error_chain! {} error_chain!{}
} }
error_chain! { error_chain! {
@ -273,7 +284,7 @@ mod foreign_link_test {
// signature of the public foreign_link_error_path // signature of the public foreign_link_error_path
#[derive(Debug)] #[derive(Debug)]
pub struct ForeignError { pub struct ForeignError {
cause: ForeignErrorCause cause: ForeignErrorCause,
} }
impl ::std::error::Error for ForeignError { impl ::std::error::Error for ForeignError {
@ -281,7 +292,9 @@ mod foreign_link_test {
"Foreign error description" "Foreign error description"
} }
fn cause(&self) -> Option<&::std::error::Error> { Some(&self.cause) } fn cause(&self) -> Option<&::std::error::Error> {
Some(&self.cause)
}
} }
impl fmt::Display for ForeignError { impl fmt::Display for ForeignError {
@ -298,7 +311,9 @@ mod foreign_link_test {
"Foreign error cause description" "Foreign error cause description"
} }
fn cause(&self) -> Option<&::std::error::Error> { None } fn cause(&self) -> Option<&::std::error::Error> {
None
}
} }
impl fmt::Display for ForeignErrorCause { impl fmt::Display for ForeignErrorCause {
@ -322,43 +337,32 @@ mod foreign_link_test {
#[test] #[test]
fn display_underlying_error() { fn display_underlying_error() {
let chained_error = try_foreign_error().err().unwrap(); let chained_error = try_foreign_error().err().unwrap();
assert_eq!( assert_eq!(format!("{}", ForeignError { cause: ForeignErrorCause {} }),
format!("{}", ForeignError{ cause: ForeignErrorCause{} }), format!("{}", chained_error));
format!("{}", chained_error)
);
} }
#[test] #[test]
fn finds_cause() { fn finds_cause() {
let chained_error = try_foreign_error().err().unwrap(); let chained_error = try_foreign_error().err().unwrap();
assert_eq!( assert_eq!(format!("{}", ForeignErrorCause {}),
format!("{}", ForeignErrorCause{}), format!("{}", ::std::error::Error::cause(&chained_error).unwrap()));
format!("{}", ::std::error::Error::cause(&chained_error).unwrap())
);
} }
#[test] #[test]
fn iterates() { fn iterates() {
let chained_error = try_foreign_error().err().unwrap(); let chained_error = try_foreign_error().err().unwrap();
let mut error_iter = chained_error.iter(); let mut error_iter = chained_error.iter();
assert_eq!( assert!(!format!("{:?}", error_iter).is_empty());
format!("{}", ForeignError{ cause: ForeignErrorCause{} }), assert_eq!(format!("{}", ForeignError { cause: ForeignErrorCause {} }),
format!("{}", error_iter.next().unwrap()) format!("{}", error_iter.next().unwrap()));
); assert_eq!(format!("{}", ForeignErrorCause {}),
assert_eq!( format!("{}", error_iter.next().unwrap()));
format!("{}", ForeignErrorCause{}), assert_eq!(format!("{:?}", None as Option<&::std::error::Error>),
format!("{}", error_iter.next().unwrap()) format!("{:?}", error_iter.next()));
);
assert_eq!(
format!("{:?}", None as Option<&::std::error::Error>),
format!("{:?}", error_iter.next())
);
} }
fn try_foreign_error() -> Result<()> { fn try_foreign_error() -> Result<()> {
try!(Err(ForeignError{ Err(ForeignError { cause: ForeignErrorCause {} })?;
cause: ForeignErrorCause{}
}));
Ok(()) Ok(())
} }
} }
@ -370,9 +374,7 @@ mod attributes_test {
#[cfg(not(test))] #[cfg(not(test))]
mod inner { mod inner {
error_chain! { error_chain!{}
}
} }
error_chain! { error_chain! {
@ -420,7 +422,7 @@ fn without_result() {
#[test] #[test]
fn documentation() { fn documentation() {
mod inner { mod inner {
error_chain! {} error_chain!{}
} }
error_chain! { error_chain! {
@ -444,13 +446,13 @@ mod multiple_error_same_mod {
MyError, MyErrorKind, MyResultExt, MyResult; MyError, MyErrorKind, MyResultExt, MyResult;
} }
} }
error_chain! {} error_chain!{}
} }
#[doc(test)] #[doc(test)]
#[deny(dead_code)] #[deny(dead_code)]
mod allow_dead_code { mod allow_dead_code {
error_chain! {} error_chain!{}
} }
// Make sure links actually work! // Make sure links actually work!
@ -483,8 +485,8 @@ fn error_patterns() {
// Tuples look nice when matching errors // Tuples look nice when matching errors
match Error::from("Test") { match Error::from("Test") {
Error(ErrorKind::Msg(_), _) => { Error(ErrorKind::Msg(_), _) => {},
} _ => {},
} }
} }
@ -559,7 +561,7 @@ fn types_declarations() {
#[test] #[test]
/// Calling chain_err over a `Result` containing an error to get a chained error /// Calling chain_err over a `Result` containing an error to get a chained error
//// and constructing a MyError directly, passing it an error should be equivalent. /// and constructing a MyError directly, passing it an error should be equivalent.
fn rewrapping() { fn rewrapping() {
use std::env::VarError::{self, NotPresent, NotUnicode}; use std::env::VarError::{self, NotPresent, NotUnicode};
@ -587,9 +589,40 @@ fn rewrapping() {
NotUnicode(_) => Err(e).chain_err(|| "env var was borkæ‡å­—åŒã"), NotUnicode(_) => Err(e).chain_err(|| "env var was borkæ‡å­—åŒã"),
}); });
assert_eq!( assert_eq!(format!("{}", our_error_a.unwrap_err()),
format!("{}", our_error_a.unwrap_err()), format!("{}", our_error_b.unwrap_err()));
format!("{}", our_error_b.unwrap_err())
);
} }
#[test]
fn comma_in_errors_impl() {
error_chain! {
links { }
foreign_links { }
errors {
HttpStatus(e: u32) {
description("http request returned an unsuccessful status code"),
display("http request returned an unsuccessful status code: {}", e)
}
}
};
}
#[test]
fn trailing_comma_in_errors_impl() {
error_chain! {
links { }
foreign_links { }
errors {
HttpStatus(e: u32) {
description("http request returned an unsuccessful status code"),
display("http request returned an unsuccessful status code: {}", e),
}
}
};
}

View File

@ -50,7 +50,7 @@ dependencies = [
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cubeb-core 0.1.0", "cubeb-core 0.1.0",
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -79,7 +79,7 @@ dependencies = [
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cubeb 0.3.0", "cubeb 0.3.0",
"cubeb-core 0.1.0", "cubeb-core 0.1.0",
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -440,7 +440,7 @@ dependencies = [
[[package]] [[package]]
name = "error-chain" name = "error-chain"
version = "0.10.0" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -1592,7 +1592,7 @@ dependencies = [
"checksum encoding_c 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "93ec52324ca72f423237a413ca0e1c60654c8b3d0934fcd5fd888508dfcc4ba7" "checksum encoding_c 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "93ec52324ca72f423237a413ca0e1c60654c8b3d0934fcd5fd888508dfcc4ba7"
"checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9" "checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9"
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "926c639bfdff1f3063f76bb66245f6d2b691aa20fdbaabecc38b2947a13a4eba" "checksum euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "926c639bfdff1f3063f76bb66245f6d2b691aa20fdbaabecc38b2947a13a4eba"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ebc04f19019fff1f2d627b5581574ead502f80c48c88900575a46e0840fe5d0" "checksum foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ebc04f19019fff1f2d627b5581574ead502f80c48c88900575a46e0840fe5d0"

View File

@ -50,7 +50,7 @@ dependencies = [
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cubeb-core 0.1.0", "cubeb-core 0.1.0",
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -79,7 +79,7 @@ dependencies = [
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cubeb 0.3.0", "cubeb 0.3.0",
"cubeb-core 0.1.0", "cubeb-core 0.1.0",
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -440,7 +440,7 @@ dependencies = [
[[package]] [[package]]
name = "error-chain" name = "error-chain"
version = "0.10.0" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -1604,7 +1604,7 @@ dependencies = [
"checksum encoding_c 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "93ec52324ca72f423237a413ca0e1c60654c8b3d0934fcd5fd888508dfcc4ba7" "checksum encoding_c 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "93ec52324ca72f423237a413ca0e1c60654c8b3d0934fcd5fd888508dfcc4ba7"
"checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9" "checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9"
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "926c639bfdff1f3063f76bb66245f6d2b691aa20fdbaabecc38b2947a13a4eba" "checksum euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "926c639bfdff1f3063f76bb66245f6d2b691aa20fdbaabecc38b2947a13a4eba"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ebc04f19019fff1f2d627b5581574ead502f80c48c88900575a46e0840fe5d0" "checksum foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ebc04f19019fff1f2d627b5581574ead502f80c48c88900575a46e0840fe5d0"