601 lines
42 KiB
HTML
601 lines
42 KiB
HTML
|
<!DOCTYPE html>
|
|||
|
<html lang="en">
|
|||
|
<head>
|
|||
|
<meta charset="utf-8">
|
|||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|||
|
<meta name="generator" content="rustdoc">
|
|||
|
<meta name="description" content="API documentation for the Rust `error_chain` crate.">
|
|||
|
<meta name="keywords" content="rust, rustlang, rust-lang, error_chain">
|
|||
|
|
|||
|
<title>error_chain - Rust</title>
|
|||
|
|
|||
|
<link rel="stylesheet" type="text/css" href="../normalize.css">
|
|||
|
<link rel="stylesheet" type="text/css" href="../rustdoc.css"
|
|||
|
id="mainThemeStyle">
|
|||
|
|
|||
|
<link rel="stylesheet" type="text/css" href="../dark.css">
|
|||
|
<link rel="stylesheet" type="text/css" href="../light.css" id="themeStyle">
|
|||
|
<script src="../storage.js"></script>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
</head>
|
|||
|
<body class="rustdoc mod">
|
|||
|
<!--[if lte IE 8]>
|
|||
|
<div class="warning">
|
|||
|
This old browser is unsupported and will most likely display funky
|
|||
|
things.
|
|||
|
</div>
|
|||
|
<![endif]-->
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<nav class="sidebar">
|
|||
|
<div class="sidebar-menu">☰</div>
|
|||
|
|
|||
|
<p class='location'>Crate error_chain</p><div class="sidebar-elems"><div class="block items"><ul><li><a href="#modules">Modules</a></li><li><a href="#macros">Macros</a></li><li><a href="#structs">Structs</a></li><li><a href="#traits">Traits</a></li></ul></div><p class='location'></p><script>window.sidebarCurrent = {name: 'error_chain', ty: 'mod', relpath: '../'};</script></div>
|
|||
|
</nav>
|
|||
|
|
|||
|
<div class="theme-picker">
|
|||
|
<button id="theme-picker" aria-label="Pick another theme!">
|
|||
|
<img src="../brush.svg" width="18" alt="Pick another theme!">
|
|||
|
</button>
|
|||
|
<div id="theme-choices"></div>
|
|||
|
</div>
|
|||
|
<script src="../theme.js"></script>
|
|||
|
<nav class="sub">
|
|||
|
<form class="search-form js-only">
|
|||
|
<div class="search-container">
|
|||
|
<input class="search-input" name="search"
|
|||
|
autocomplete="off"
|
|||
|
placeholder="Click or press ‘S’ to search, ‘?’ for more options…"
|
|||
|
type="search">
|
|||
|
</div>
|
|||
|
</form>
|
|||
|
</nav>
|
|||
|
|
|||
|
<section id='main' class="content"><h1 class='fqn'><span class='in-band'>Crate <a class="mod" href=''>error_chain</a></span><span class='out-of-band'><span id='render-detail'>
|
|||
|
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
|
|||
|
[<span class='inner'>−</span>]
|
|||
|
</a>
|
|||
|
</span><a class='srclink' href='../src/error_chain/lib.rs.html#1-865' title='goto source code'>[src]</a></span></h1><div class='docblock'><p>A library for consistent and reliable error handling</p>
|
|||
|
<p>error-chain makes it easy to take full advantage of Rust's
|
|||
|
powerful error handling features without the overhead of
|
|||
|
maintaining boilerplate error types and conversions. It implements
|
|||
|
an opinionated strategy for defining your own error types, as well
|
|||
|
as conversions from others' error types.</p>
|
|||
|
<h2 id="quick-start" class="section-header"><a href="#quick-start">Quick start</a></h2>
|
|||
|
<p>If you just want to set up your new project with error-chain,
|
|||
|
follow the <a href="https://github.com/rust-lang-nursery/error-chain/blob/master/examples/quickstart.rs">quickstart.rs</a> template, and read this <a href="http://brson.github.io/2016/11/30/starting-with-error-chain">intro</a>
|
|||
|
to error-chain.</p>
|
|||
|
<h2 id="why-error-chain" class="section-header"><a href="#why-error-chain">Why error chain?</a></h2>
|
|||
|
<ul>
|
|||
|
<li>error-chain is easy to configure. Handle errors robustly with minimal
|
|||
|
effort.</li>
|
|||
|
<li>Basic error handling requires no maintenance of custom error types
|
|||
|
nor the <a href="https://doc.rust-lang.org/std/convert/trait.From.html"><code>From</code></a> conversions that make <code>?</code> work.</li>
|
|||
|
<li>error-chain scales from simple error handling strategies to more
|
|||
|
rigorous. Return formatted strings for simple errors, only
|
|||
|
introducing error variants and their strong typing as needed for
|
|||
|
advanced error recovery.</li>
|
|||
|
<li>error-chain makes it trivial to correctly manage the <a href="https://doc.rust-lang.org/std/error/trait.Error.html#method.cause">cause</a> of
|
|||
|
the errors generated by your own code. This is the "chaining"
|
|||
|
in "error-chain".</li>
|
|||
|
</ul>
|
|||
|
<h2 id="principles-of-error-chain" class="section-header"><a href="#principles-of-error-chain">Principles of error-chain</a></h2>
|
|||
|
<p>error-chain is based on the following principles:</p>
|
|||
|
<ul>
|
|||
|
<li>No error should ever be discarded. This library primarily
|
|||
|
makes it easy to "chain" errors with the <a href="example_generated/trait.ResultExt.html#tymethod.chain_err"><code>chain_err</code></a> method.</li>
|
|||
|
<li>Introducing new errors is trivial. Simple errors can be introduced
|
|||
|
at the error site with just a string.</li>
|
|||
|
<li>Handling errors is possible with pattern matching.</li>
|
|||
|
<li>Conversions between error types are done in an automatic and
|
|||
|
consistent way - <a href="https://doc.rust-lang.org/std/convert/trait.From.html"><code>From</code></a> conversion behavior is never specified
|
|||
|
explicitly.</li>
|
|||
|
<li>Errors implement <a href="https://doc.rust-lang.org/std/marker/trait.Send.html"><code>Send</code></a>.</li>
|
|||
|
<li>Errors can carry backtraces.</li>
|
|||
|
</ul>
|
|||
|
<p>Similar to other libraries like <a href="https://github.com/DanielKeep/rust-error-type">error-type</a> and <a href="https://github.com/tailhook/quick-error">quick-error</a>,
|
|||
|
this library introduces the error chaining mechanism originally
|
|||
|
employed by Cargo. The <a href="macro.error_chain.html"><code>error_chain!</code></a> macro declares the types
|
|||
|
and implementation boilerplate necessary for fulfilling a
|
|||
|
particular error-handling strategy. Most importantly it defines a
|
|||
|
custom error type (called <a href="example_generated/struct.Error.html"><code>Error</code></a> by convention) and the <a href="https://doc.rust-lang.org/std/convert/trait.From.html"><code>From</code></a>
|
|||
|
conversions that let the <code>?</code> operator work.</p>
|
|||
|
<p>This library differs in a few ways from previous error libs:</p>
|
|||
|
<ul>
|
|||
|
<li>Instead of defining the custom <a href="example_generated/struct.Error.html"><code>Error</code></a> type as an enum, it is a
|
|||
|
struct containing an <a href="example_generated/enum.ErrorKind.html"><code>ErrorKind</code></a> (which defines the
|
|||
|
<a href="example_generated/enum.ErrorKind.html#method.description"><code>description</code></a> and <a href="trait.ChainedError.html#method.display_chain"><code>display_chain</code></a> methods for the error), an opaque,
|
|||
|
optional, boxed <a href="https://doc.rust-lang.org/std/error/trait.Error.html"><code>std::error::Error</code></a><code>+</code><a href="https://doc.rust-lang.org/std/marker/trait.Send.html"><code>Send</code></a><code>+ 'static</code> object
|
|||
|
(which defines the <a href="example_generated/struct.Error.html#method.cause"><code>cause</code></a>, and establishes the links in the
|
|||
|
error chain), and a <a href="struct.Backtrace.html"><code>Backtrace</code></a>.</li>
|
|||
|
<li>The macro also defines a <a href="example_generated/trait.ResultExt.html"><code>ResultExt</code></a> trait that defines a
|
|||
|
<a href="example_generated/trait.ResultExt.html#tymethod.chain_err"><code>chain_err</code></a> method. This method on all <a href="https://doc.rust-lang.org/std/error/trait.Error.html"><code>std::error::Error</code></a><code>+</code><a href="https://doc.rust-lang.org/std/marker/trait.Send.html"><code>Send</code></a><code>+ 'static</code>
|
|||
|
types extends the error chain by boxing the current
|
|||
|
error into an opaque object and putting it inside a new concrete
|
|||
|
error.</li>
|
|||
|
<li>It provides automatic <a href="https://doc.rust-lang.org/std/convert/trait.From.html"><code>From</code></a> conversions between other error types
|
|||
|
defined by the <a href="macro.error_chain.html"><code>error_chain!</code></a> that preserve type information,
|
|||
|
and facilitate seamless error composition and matching of composed
|
|||
|
errors.</li>
|
|||
|
<li>It provides automatic <a href="https://doc.rust-lang.org/std/convert/trait.From.html"><code>From</code></a> conversions between any other error
|
|||
|
type that hides the type of the other error in the <a href="example_generated/struct.Error.html#method.cause"><code>cause</code></a> box.</li>
|
|||
|
<li>If <code>RUST_BACKTRACE</code> is enabled, it collects a single backtrace at
|
|||
|
the earliest opportunity and propagates it down the stack through
|
|||
|
<a href="https://doc.rust-lang.org/std/convert/trait.From.html"><code>From</code></a> and <a href="example_generated/trait.ResultExt.html"><code>ResultExt</code></a> conversions.</li>
|
|||
|
</ul>
|
|||
|
<p>To accomplish its goals it makes some tradeoffs:</p>
|
|||
|
<ul>
|
|||
|
<li>The split between the <a href="example_generated/struct.Error.html"><code>Error</code></a> and <a href="example_generated/enum.ErrorKind.html"><code>ErrorKind</code></a> types can make it
|
|||
|
slightly more cumbersome to instantiate new (unchained) errors,
|
|||
|
requiring an <a href="https://doc.rust-lang.org/std/convert/trait.Into.html"><code>Into</code></a> or <a href="https://doc.rust-lang.org/std/convert/trait.From.html"><code>From</code></a> conversion; as well as slightly
|
|||
|
more cumbersome to match on errors with another layer of types
|
|||
|
to match.</li>
|
|||
|
<li>Because the error type contains <a href="https://doc.rust-lang.org/std/error/trait.Error.html"><code>std::error::Error</code></a><code>+</code><a href="https://doc.rust-lang.org/std/marker/trait.Send.html"><code>Send</code></a><code>+ 'static</code> objects,
|
|||
|
it can't implement <a href="https://doc.rust-lang.org/std/cmp/trait.PartialEq.html"><code>PartialEq</code></a> for easy comparisons.</li>
|
|||
|
</ul>
|
|||
|
<h2 id="declaring-error-types" class="section-header"><a href="#declaring-error-types">Declaring error types</a></h2>
|
|||
|
<p>Generally, you define one family of error types per crate, though
|
|||
|
it's also perfectly fine to define error types on a finer-grained
|
|||
|
basis, such as per module.</p>
|
|||
|
<p>Assuming you are using crate-level error types, typically you will
|
|||
|
define an <code>errors</code> module and inside it call <a href="macro.error_chain.html"><code>error_chain!</code></a>:</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="kw">mod</span> <span class="ident">other_error</span> {
|
|||
|
<span class="macro">error_chain</span><span class="macro">!</span> {}
|
|||
|
}
|
|||
|
|
|||
|
<span class="macro">error_chain</span><span class="macro">!</span> {
|
|||
|
<span class="comment">// The type defined for this error. These are the conventional</span>
|
|||
|
<span class="comment">// and recommended names, but they can be arbitrarily chosen.</span>
|
|||
|
<span class="comment">//</span>
|
|||
|
<span class="comment">// It is also possible to leave this section out entirely, or</span>
|
|||
|
<span class="comment">// leave it empty, and these names will be used automatically.</span>
|
|||
|
<span class="ident">types</span> {
|
|||
|
<span class="ident">Error</span>, <span class="ident">ErrorKind</span>, <span class="ident">ResultExt</span>, <span class="prelude-ty">Result</span>;
|
|||
|
}
|
|||
|
|
|||
|
<span class="comment">// Without the `Result` wrapper:</span>
|
|||
|
<span class="comment">//</span>
|
|||
|
<span class="comment">// types {</span>
|
|||
|
<span class="comment">// Error, ErrorKind, ResultExt;</span>
|
|||
|
<span class="comment">// }</span>
|
|||
|
|
|||
|
<span class="comment">// Automatic conversions between this error chain and other</span>
|
|||
|
<span class="comment">// error chains. In this case, it will e.g. generate an</span>
|
|||
|
<span class="comment">// `ErrorKind` variant called `Another` which in turn contains</span>
|
|||
|
<span class="comment">// the `other_error::ErrorKind`, with conversions from</span>
|
|||
|
<span class="comment">// `other_error::Error`.</span>
|
|||
|
<span class="comment">//</span>
|
|||
|
<span class="comment">// Optionally, some attributes can be added to a variant.</span>
|
|||
|
<span class="comment">//</span>
|
|||
|
<span class="comment">// This section can be empty.</span>
|
|||
|
<span class="ident">links</span> {
|
|||
|
<span class="ident">Another</span>(<span class="ident">other_error</span>::<span class="ident">Error</span>, <span class="ident">other_error</span>::<span class="ident">ErrorKind</span>) <span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">unix</span>)]</span>;
|
|||
|
}
|
|||
|
|
|||
|
<span class="comment">// Automatic conversions between this error chain and other</span>
|
|||
|
<span class="comment">// error types not defined by the `error_chain!`. These will be</span>
|
|||
|
<span class="comment">// wrapped in a new error with, in the first case, the</span>
|
|||
|
<span class="comment">// `ErrorKind::Fmt` variant. The description and cause will</span>
|
|||
|
<span class="comment">// forward to the description and cause of the original error.</span>
|
|||
|
<span class="comment">//</span>
|
|||
|
<span class="comment">// Optionally, some attributes can be added to a variant.</span>
|
|||
|
<span class="comment">//</span>
|
|||
|
<span class="comment">// This section can be empty.</span>
|
|||
|
<span class="ident">foreign_links</span> {
|
|||
|
<span class="ident">Fmt</span>(::<span class="ident">std</span>::<span class="ident">fmt</span>::<span class="ident">Error</span>);
|
|||
|
<span class="ident">Io</span>(::<span class="ident">std</span>::<span class="ident">io</span>::<span class="ident">Error</span>) <span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">unix</span>)]</span>;
|
|||
|
}
|
|||
|
|
|||
|
<span class="comment">// Define additional `ErrorKind` variants. Define custom responses with the</span>
|
|||
|
<span class="comment">// `description` and `display` calls.</span>
|
|||
|
<span class="ident">errors</span> {
|
|||
|
<span class="ident">InvalidToolchainName</span>(<span class="ident">t</span>: <span class="ident">String</span>) {
|
|||
|
<span class="ident">description</span>(<span class="string">"invalid toolchain name"</span>)
|
|||
|
<span class="ident">display</span>(<span class="string">"invalid toolchain name: '{}'"</span>, <span class="ident">t</span>)
|
|||
|
}
|
|||
|
|
|||
|
<span class="comment">// You can also add commas after description/display.</span>
|
|||
|
<span class="comment">// This may work better with some editor auto-indentation modes:</span>
|
|||
|
<span class="ident">UnknownToolchainVersion</span>(<span class="ident">v</span>: <span class="ident">String</span>) {
|
|||
|
<span class="ident">description</span>(<span class="string">"unknown toolchain version"</span>), <span class="comment">// note the ,</span>
|
|||
|
<span class="ident">display</span>(<span class="string">"unknown toolchain version: '{}'"</span>, <span class="ident">v</span>), <span class="comment">// trailing comma is allowed</span>
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</pre>
|
|||
|
<p>Each section, <code>types</code>, <code>links</code>, <code>foreign_links</code>, and <code>errors</code> may
|
|||
|
be omitted if it is empty.</p>
|
|||
|
<p>This populates the module with a number of definitions,
|
|||
|
the most important of which are the <a href="example_generated/struct.Error.html"><code>Error</code></a> type
|
|||
|
and the <a href="example_generated/enum.ErrorKind.html"><code>ErrorKind</code></a> type. An example of generated code can be found in the
|
|||
|
<a href="example_generated/index.html">example_generated</a> module.</p>
|
|||
|
<h2 id="returning-new-errors" class="section-header"><a href="#returning-new-errors">Returning new errors</a></h2>
|
|||
|
<p>Introducing new error chains, with a string message:</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="kw">fn</span> <span class="ident">foo</span>() <span class="op">-></span> <span class="prelude-ty">Result</span><span class="op"><</span>()<span class="op">></span> {
|
|||
|
<span class="prelude-val">Err</span>(<span class="string">"foo error!"</span>.<span class="ident">into</span>())
|
|||
|
}</pre>
|
|||
|
<p>Introducing new error chains, with an <a href="example_generated/enum.ErrorKind.html"><code>ErrorKind</code></a>:</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="macro">error_chain</span><span class="macro">!</span> {
|
|||
|
<span class="ident">errors</span> { <span class="ident">FooError</span> }
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">fn</span> <span class="ident">foo</span>() <span class="op">-></span> <span class="prelude-ty">Result</span><span class="op"><</span>()<span class="op">></span> {
|
|||
|
<span class="prelude-val">Err</span>(<span class="ident">ErrorKind</span>::<span class="ident">FooError</span>.<span class="ident">into</span>())
|
|||
|
}</pre>
|
|||
|
<p>Note that the return type is the typedef <a href="example_generated/type.Result.html"><code>Result</code></a>, which is
|
|||
|
defined by the macro as <code>pub type Result<T> = ::std::result::Result<T, Error></code>. Note that in both cases
|
|||
|
<a href="https://doc.rust-lang.org/std/convert/trait.Into.html#tymethod.into"><code>.into()</code></a> is called to convert a type into the <a href="example_generated/struct.Error.html"><code>Error</code></a> type; both
|
|||
|
strings and <a href="example_generated/enum.ErrorKind.html"><code>ErrorKind</code></a> have <a href="https://doc.rust-lang.org/std/convert/trait.From.html"><code>From</code></a> conversions to turn them into
|
|||
|
<a href="example_generated/struct.Error.html"><code>Error</code></a>.</p>
|
|||
|
<p>When the error is emitted behind the <code>?</code> operator, the explicit conversion
|
|||
|
isn't needed; <code>Err(ErrorKind)</code> will automatically be converted to <code>Err(Error)</code>.
|
|||
|
So the below is equivalent to the previous:</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="kw">fn</span> <span class="ident">foo</span>() <span class="op">-></span> <span class="prelude-ty">Result</span><span class="op"><</span>()<span class="op">></span> {
|
|||
|
<span class="prelude-val">Ok</span>(<span class="prelude-val">Err</span>(<span class="ident">ErrorKind</span>::<span class="ident">FooError</span>)<span class="question-mark">?</span>)
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">fn</span> <span class="ident">bar</span>() <span class="op">-></span> <span class="prelude-ty">Result</span><span class="op"><</span>()<span class="op">></span> {
|
|||
|
<span class="prelude-val">Ok</span>(<span class="prelude-val">Err</span>(<span class="string">"bogus!"</span>)<span class="question-mark">?</span>)
|
|||
|
}</pre>
|
|||
|
<h2 id="the-bail-macro" class="section-header"><a href="#the-bail-macro">The <code>bail!</code> macro</a></h2>
|
|||
|
<p>The above method of introducing new errors works but is a little
|
|||
|
verbose. Instead, we can use the <a href="macro.bail.html"><code>bail!</code></a> macro, which performs an early return
|
|||
|
with conversions done automatically.</p>
|
|||
|
<p>With <a href="macro.bail.html"><code>bail!</code></a> the previous examples look like:</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="kw">fn</span> <span class="ident">foo</span>() <span class="op">-></span> <span class="prelude-ty">Result</span><span class="op"><</span>()<span class="op">></span> {
|
|||
|
<span class="kw">if</span> <span class="bool-val">true</span> {
|
|||
|
<span class="macro">bail</span><span class="macro">!</span>(<span class="ident">ErrorKind</span>::<span class="ident">FooError</span>);
|
|||
|
} <span class="kw">else</span> {
|
|||
|
<span class="prelude-val">Ok</span>(())
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">fn</span> <span class="ident">bar</span>() <span class="op">-></span> <span class="prelude-ty">Result</span><span class="op"><</span>()<span class="op">></span> {
|
|||
|
<span class="kw">if</span> <span class="bool-val">true</span> {
|
|||
|
<span class="macro">bail</span><span class="macro">!</span>(<span class="string">"bogus!"</span>);
|
|||
|
} <span class="kw">else</span> {
|
|||
|
<span class="prelude-val">Ok</span>(())
|
|||
|
}
|
|||
|
}</pre>
|
|||
|
<h2 id="chaining-errors" class="section-header"><a href="#chaining-errors">Chaining errors</a></h2>
|
|||
|
<p>error-chain supports extending an error chain by appending new errors.
|
|||
|
This can be done on a Result or on an existing Error.</p>
|
|||
|
<p>To extend the error chain:</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="kw">let</span> <span class="ident">res</span>: <span class="prelude-ty">Result</span><span class="op"><</span>()<span class="op">></span> <span class="op">=</span> <span class="ident">do_something</span>().<span class="ident">chain_err</span>(<span class="op">||</span> <span class="string">"something went wrong"</span>);</pre>
|
|||
|
<p><a href="example_generated/trait.ResultExt.html#tymethod.chain_err"><code>chain_err</code></a> can be called on any <a href="example_generated/type.Result.html"><code>Result</code></a> type where the contained
|
|||
|
error type implements <a href="https://doc.rust-lang.org/std/error/trait.Error.html"><code>std::error::Error</code></a><code>+</code><a href="https://doc.rust-lang.org/std/marker/trait.Send.html"><code>Send</code></a><code>+ 'static</code>, as long as
|
|||
|
the <a href="example_generated/type.Result.html"><code>Result</code></a> type's corresponding <a href="example_generated/trait.ResultExt.html"><code>ResultExt</code></a> trait is in scope. If
|
|||
|
the <a href="example_generated/type.Result.html"><code>Result</code></a> is an <code>Err</code> then <a href="example_generated/trait.ResultExt.html#tymethod.chain_err"><code>chain_err</code></a> evaluates the closure,
|
|||
|
which returns <em>some type that can be converted to <a href="example_generated/enum.ErrorKind.html"><code>ErrorKind</code></a></em>,
|
|||
|
boxes the original error to store as the cause, then returns a new
|
|||
|
error containing the original error.</p>
|
|||
|
<p>Calling <a href="example_generated/struct.Error.html#method.chain_err"><code>chain_err</code></a> on an existing <a href="example_generated/struct.Error.html"><code>Error</code></a> instance has
|
|||
|
the same signature and produces the same outcome as being called on a
|
|||
|
<a href="example_generated/type.Result.html"><code>Result</code></a> matching the properties described above. This is most useful when
|
|||
|
partially handling errors using the <a href="https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err"><code>map_err</code></a> function.</p>
|
|||
|
<p>To chain an error directly, use <a href="example_generated/struct.Error.html#method.with_chain"><code>with_chain</code></a>:</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="kw">let</span> <span class="ident">res</span>: <span class="prelude-ty">Result</span><span class="op"><</span>()<span class="op">></span> <span class="op">=</span>
|
|||
|
<span class="ident">do_something</span>().<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> <span class="ident">Error</span>::<span class="ident">with_chain</span>(<span class="ident">e</span>, <span class="string">"something went wrong"</span>));</pre>
|
|||
|
<h2 id="linking-errors" class="section-header"><a href="#linking-errors">Linking errors</a></h2>
|
|||
|
<p>To convert an error from another error chain to this error chain:</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="macro">error_chain</span><span class="macro">!</span> {
|
|||
|
<span class="ident">links</span> {
|
|||
|
<span class="ident">OtherError</span>(<span class="ident">other</span>::<span class="ident">Error</span>, <span class="ident">other</span>::<span class="ident">ErrorKind</span>);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">fn</span> <span class="ident">do_other_thing</span>() <span class="op">-></span> <span class="ident">other</span>::<span class="prelude-ty">Result</span><span class="op"><</span>()<span class="op">></span> { <span class="macro">unimplemented</span><span class="macro">!</span>() }
|
|||
|
|
|||
|
<span class="kw">let</span> <span class="ident">res</span>: <span class="prelude-ty">Result</span><span class="op"><</span>()<span class="op">></span> <span class="op">=</span> <span class="ident">do_other_thing</span>().<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> <span class="ident">e</span>.<span class="ident">into</span>());</pre>
|
|||
|
<p>The <a href="example_generated/struct.Error.html"><code>Error</code></a> and <a href="example_generated/enum.ErrorKind.html"><code>ErrorKind</code></a> types implements <a href="https://doc.rust-lang.org/std/convert/trait.From.html"><code>From</code></a> for the corresponding
|
|||
|
types of all linked error chains. Linked errors do not introduce a new
|
|||
|
cause to the error chain.</p>
|
|||
|
<h2 id="matching-errors" class="section-header"><a href="#matching-errors">Matching errors</a></h2>
|
|||
|
<p>error-chain error variants are matched with simple patterns.
|
|||
|
<a href="example_generated/struct.Error.html"><code>Error</code></a> is a tuple struct and its first field is the <a href="example_generated/enum.ErrorKind.html"><code>ErrorKind</code></a>,
|
|||
|
making dispatching on error kinds relatively compact:</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="macro">error_chain</span><span class="macro">!</span> {
|
|||
|
<span class="ident">errors</span> {
|
|||
|
<span class="ident">InvalidToolchainName</span>(<span class="ident">t</span>: <span class="ident">String</span>) {
|
|||
|
<span class="ident">description</span>(<span class="string">"invalid toolchain name"</span>)
|
|||
|
<span class="ident">display</span>(<span class="string">"invalid toolchain name: '{}'"</span>, <span class="ident">t</span>)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">match</span> <span class="ident">Error</span>::<span class="ident">from</span>(<span class="string">"error!"</span>) {
|
|||
|
<span class="ident">Error</span>(<span class="ident">ErrorKind</span>::<span class="ident">InvalidToolchainName</span>(<span class="kw">_</span>), <span class="kw">_</span>) <span class="op">=></span> { }
|
|||
|
<span class="ident">Error</span>(<span class="ident">ErrorKind</span>::<span class="ident">Msg</span>(<span class="kw">_</span>), <span class="kw">_</span>) <span class="op">=></span> { }
|
|||
|
<span class="kw">_</span> <span class="op">=></span> { }
|
|||
|
}</pre>
|
|||
|
<p>Chained errors are also matched with (relatively) compact syntax</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="kw">mod</span> <span class="ident">utils</span> {
|
|||
|
<span class="macro">error_chain</span><span class="macro">!</span> {
|
|||
|
<span class="ident">errors</span> {
|
|||
|
<span class="ident">BadStuff</span> {
|
|||
|
<span class="ident">description</span>(<span class="string">"bad stuff"</span>)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">mod</span> <span class="ident">app</span> {
|
|||
|
<span class="macro">error_chain</span><span class="macro">!</span> {
|
|||
|
<span class="ident">links</span> {
|
|||
|
<span class="ident">Utils</span>(::<span class="ident">utils</span>::<span class="ident">Error</span>, ::<span class="ident">utils</span>::<span class="ident">ErrorKind</span>);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
<span class="kw">match</span> <span class="ident">app</span>::<span class="ident">Error</span>::<span class="ident">from</span>(<span class="string">"error!"</span>) {
|
|||
|
<span class="ident">app</span>::<span class="ident">Error</span>(<span class="ident">app</span>::<span class="ident">ErrorKind</span>::<span class="ident">Utils</span>(<span class="ident">utils</span>::<span class="ident">ErrorKind</span>::<span class="ident">BadStuff</span>), <span class="kw">_</span>) <span class="op">=></span> { }
|
|||
|
<span class="kw">_</span> <span class="op">=></span> { }
|
|||
|
}</pre>
|
|||
|
<h2 id="inspecting-errors" class="section-header"><a href="#inspecting-errors">Inspecting errors</a></h2>
|
|||
|
<p>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.</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="kw">use</span> <span class="ident">error_chain</span>::<span class="ident">ChainedError</span>; <span class="comment">// for e.display_chain()</span>
|
|||
|
|
|||
|
<span class="macro">error_chain</span><span class="macro">!</span> {
|
|||
|
<span class="ident">errors</span> {
|
|||
|
<span class="ident">InvalidToolchainName</span>(<span class="ident">t</span>: <span class="ident">String</span>) {
|
|||
|
<span class="ident">description</span>(<span class="string">"invalid toolchain name"</span>)
|
|||
|
<span class="ident">display</span>(<span class="string">"invalid toolchain name: '{}'"</span>, <span class="ident">t</span>)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
<span class="comment">// Generate an example error to inspect:</span>
|
|||
|
<span class="kw">let</span> <span class="ident">e</span> <span class="op">=</span> <span class="string">"xyzzy"</span>.<span class="ident">parse</span>::<span class="op"><</span><span class="ident">i32</span><span class="op">></span>()
|
|||
|
.<span class="ident">chain_err</span>(<span class="op">||</span> <span class="ident">ErrorKind</span>::<span class="ident">InvalidToolchainName</span>(<span class="string">"xyzzy"</span>.<span class="ident">to_string</span>()))
|
|||
|
.<span class="ident">unwrap_err</span>();
|
|||
|
|
|||
|
<span class="comment">// Get the brief description of the error:</span>
|
|||
|
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">e</span>.<span class="ident">description</span>(), <span class="string">"invalid toolchain name"</span>);
|
|||
|
|
|||
|
<span class="comment">// Get the display version of the error:</span>
|
|||
|
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">e</span>.<span class="ident">to_string</span>(), <span class="string">"invalid toolchain name: 'xyzzy'"</span>);
|
|||
|
|
|||
|
<span class="comment">// Get the full cause and backtrace:</span>
|
|||
|
<span class="macro">println</span><span class="macro">!</span>(<span class="string">"{}"</span>, <span class="ident">e</span>.<span class="ident">display_chain</span>().<span class="ident">to_string</span>());
|
|||
|
<span class="comment">// Error: invalid toolchain name: 'xyzzy'</span>
|
|||
|
<span class="comment">// Caused by: invalid digit found in string</span>
|
|||
|
<span class="comment">// stack backtrace:</span>
|
|||
|
<span class="comment">// 0: 0x7fa9f684fc94 - backtrace::backtrace::libunwind::trace</span>
|
|||
|
<span class="comment">// at src/backtrace/libunwind.rs:53</span>
|
|||
|
<span class="comment">// - backtrace::backtrace::trace<closure></span>
|
|||
|
<span class="comment">// at src/backtrace/mod.rs:42</span>
|
|||
|
<span class="comment">// 1: 0x7fa9f6850b0e - backtrace::capture::{{impl}}::new</span>
|
|||
|
<span class="comment">// at out/capture.rs:79</span>
|
|||
|
<span class="comment">// [..]</span></pre>
|
|||
|
<p>The <a href="example_generated/struct.Error.html"><code>Error</code></a> and <a href="example_generated/enum.ErrorKind.html"><code>ErrorKind</code></a> types also allow programmatic access to these elements.</p>
|
|||
|
<h2 id="foreign-links" class="section-header"><a href="#foreign-links">Foreign links</a></h2>
|
|||
|
<p>Errors that do not conform to the same conventions as this library
|
|||
|
can still be included in the error chain. They are considered "foreign
|
|||
|
errors", and are declared using the <code>foreign_links</code> block of the
|
|||
|
<a href="macro.error_chain.html"><code>error_chain!</code></a> macro. <a href="example_generated/struct.Error.html"><code>Error</code></a>s are automatically created from
|
|||
|
foreign errors by the <code>?</code> operator.</p>
|
|||
|
<p>Foreign links and regular links have one crucial difference:
|
|||
|
<a href="https://doc.rust-lang.org/std/convert/trait.From.html"><code>From</code></a> conversions for regular links <em>do not introduce a new error
|
|||
|
into the error chain</em>, while conversions for foreign links <em>always
|
|||
|
introduce a new error into the error chain</em>. So for the example
|
|||
|
above all errors deriving from the <a href="https://doc.rust-lang.org/std/fmt/struct.Error.html"><code>std::fmt::Error</code></a> type will be
|
|||
|
presented to the user as a new <a href="example_generated/enum.ErrorKind.html"><code>ErrorKind</code></a> variant, and the
|
|||
|
cause will be the original <a href="https://doc.rust-lang.org/std/fmt/struct.Error.html"><code>std::fmt::Error</code></a> error. In contrast, when
|
|||
|
<code>other_error::Error</code> is converted to <code>Error</code> the two <code>ErrorKind</code>s
|
|||
|
are converted between each other to create a new <code>Error</code> but the
|
|||
|
old error is discarded; there is no "cause" created from the
|
|||
|
original error.</p>
|
|||
|
<h2 id="backtraces" class="section-header"><a href="#backtraces">Backtraces</a></h2>
|
|||
|
<p>If the <code>RUST_BACKTRACE</code> environment variable is set to anything
|
|||
|
but <code>0</code>, the earliest non-foreign error to be generated creates
|
|||
|
a single backtrace, which is passed through all <a href="https://doc.rust-lang.org/std/convert/trait.From.html"><code>From</code></a> conversions
|
|||
|
and <a href="example_generated/trait.ResultExt.html#tymethod.chain_err"><code>chain_err</code></a> invocations of compatible types. To read the
|
|||
|
backtrace just call the <a href="struct.Backtrace.html"><code>backtrace</code></a> method.</p>
|
|||
|
<p>Backtrace generation can be disabled by turning off the <code>backtrace</code> feature.</p>
|
|||
|
<p>The Backtrace contains a Vec of <a href="https://docs.rs/backtrace/0.3.2/backtrace/struct.BacktraceFrame.html"><code>BacktraceFrame</code></a>s that can be operated
|
|||
|
on directly. For example, to only see the files and line numbers of code
|
|||
|
within your own project.</p>
|
|||
|
|
|||
|
<pre class="rust rust-example-rendered">
|
|||
|
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="kw-2">ref</span> <span class="ident">e</span>) <span class="op">=</span> <span class="ident">open_file</span>() {
|
|||
|
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">backtrace</span>) <span class="op">=</span> <span class="ident">e</span>.<span class="ident">backtrace</span>() {
|
|||
|
<span class="kw">let</span> <span class="ident">frames</span> <span class="op">=</span> <span class="ident">backtrace</span>.<span class="ident">frames</span>();
|
|||
|
<span class="kw">for</span> <span class="ident">frame</span> <span class="kw">in</span> <span class="ident">frames</span>.<span class="ident">iter</span>() {
|
|||
|
<span class="kw">for</span> <span class="ident">symbol</span> <span class="kw">in</span> <span class="ident">frame</span>.<span class="ident">symbols</span>().<span class="ident">iter</span>() {
|
|||
|
<span class="kw">if</span> <span class="kw">let</span> (<span class="prelude-val">Some</span>(<span class="ident">file</span>), <span class="prelude-val">Some</span>(<span class="ident">lineno</span>)) <span class="op">=</span> (<span class="ident">symbol</span>.<span class="ident">filename</span>(), <span class="ident">symbol</span>.<span class="ident">lineno</span>()) {
|
|||
|
<span class="kw">if</span> <span class="ident">file</span>.<span class="ident">display</span>().<span class="ident">to_string</span>()[<span class="number">0</span>..<span class="number">3</span>] <span class="op">==</span> <span class="string">"src"</span>.<span class="ident">to_string</span>(){
|
|||
|
<span class="macro">println</span><span class="macro">!</span>(<span class="string">"{}:{}"</span>, <span class="ident">file</span>.<span class="ident">display</span>().<span class="ident">to_string</span>(), <span class="ident">lineno</span>);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
<span class="kw">fn</span> <span class="ident">open_file</span>() <span class="op">-></span> <span class="prelude-ty">Result</span><span class="op"><</span>()<span class="op">></span> {
|
|||
|
<span class="ident">std</span>::<span class="ident">fs</span>::<span class="ident">File</span>::<span class="ident">open</span>(<span class="string">"does_not_exist"</span>)<span class="question-mark">?</span>;
|
|||
|
<span class="prelude-val">Ok</span>(())
|
|||
|
}</pre>
|
|||
|
<h2 id="iteration" class="section-header"><a href="#iteration">Iteration</a></h2>
|
|||
|
<p>The <a href="example_generated/struct.Error.html#method.iter"><code>iter</code></a> method returns an iterator over the chain of error boxes.</p>
|
|||
|
</div><h2 id='modules' class='section-header'><a href="#modules">Modules</a></h2>
|
|||
|
<table>
|
|||
|
<tr class=' module-item'>
|
|||
|
<td><a class="mod" href="example_generated/index.html"
|
|||
|
title='mod error_chain::example_generated'>example_generated</a></td>
|
|||
|
<td class='docblock-short'>
|
|||
|
<p>These modules show an example of code generated by the macro. <strong>IT MUST NOT BE
|
|||
|
USED OUTSIDE THIS CRATE</strong>.</p>
|
|||
|
|
|||
|
</td>
|
|||
|
</tr></table><h2 id='macros' class='section-header'><a href="#macros">Macros</a></h2>
|
|||
|
<table>
|
|||
|
<tr class=' module-item'>
|
|||
|
<td><a class="macro" href="macro.bail.html"
|
|||
|
title='macro error_chain::bail'>bail</a></td>
|
|||
|
<td class='docblock-short'>
|
|||
|
<p>Exits a function early with an error</p>
|
|||
|
|
|||
|
</td>
|
|||
|
</tr>
|
|||
|
<tr class=' module-item'>
|
|||
|
<td><a class="macro" href="macro.ensure.html"
|
|||
|
title='macro error_chain::ensure'>ensure</a></td>
|
|||
|
<td class='docblock-short'>
|
|||
|
<p>Exits a function early with an error if the condition is not satisfied</p>
|
|||
|
|
|||
|
</td>
|
|||
|
</tr>
|
|||
|
<tr class=' module-item'>
|
|||
|
<td><a class="macro" href="macro.error_chain.html"
|
|||
|
title='macro error_chain::error_chain'>error_chain</a></td>
|
|||
|
<td class='docblock-short'>
|
|||
|
<p>Macro for generating error types and traits. See crate level documentation for details.</p>
|
|||
|
|
|||
|
</td>
|
|||
|
</tr>
|
|||
|
<tr class=' module-item'>
|
|||
|
<td><a class="macro" href="macro.quick_main.html"
|
|||
|
title='macro error_chain::quick_main'>quick_main</a></td>
|
|||
|
<td class='docblock-short'>
|
|||
|
<p>Convenient wrapper to be able to use <code>?</code> and such in the main. You can
|
|||
|
use it with a separated function:</p>
|
|||
|
|
|||
|
</td>
|
|||
|
</tr></table><h2 id='structs' class='section-header'><a href="#structs">Structs</a></h2>
|
|||
|
<table>
|
|||
|
<tr class=' module-item'>
|
|||
|
<td><a class="struct" href="struct.Backtrace.html"
|
|||
|
title='struct error_chain::Backtrace'>Backtrace</a></td>
|
|||
|
<td class='docblock-short'>
|
|||
|
<p>Representation of an owned and self-contained backtrace.</p>
|
|||
|
|
|||
|
</td>
|
|||
|
</tr>
|
|||
|
<tr class=' module-item'>
|
|||
|
<td><a class="struct" href="struct.DisplayChain.html"
|
|||
|
title='struct error_chain::DisplayChain'>DisplayChain</a></td>
|
|||
|
<td class='docblock-short'>
|
|||
|
<p>A struct which formats an error for output.</p>
|
|||
|
|
|||
|
</td>
|
|||
|
</tr>
|
|||
|
<tr class=' module-item'>
|
|||
|
<td><a class="struct" href="struct.Iter.html"
|
|||
|
title='struct error_chain::Iter'>Iter</a></td>
|
|||
|
<td class='docblock-short'>
|
|||
|
<p>Iterator over the error chain using the <code>Error::cause()</code> method.</p>
|
|||
|
|
|||
|
</td>
|
|||
|
</tr></table><h2 id='traits' class='section-header'><a href="#traits">Traits</a></h2>
|
|||
|
<table>
|
|||
|
<tr class=' module-item'>
|
|||
|
<td><a class="trait" href="trait.ChainedError.html"
|
|||
|
title='trait error_chain::ChainedError'>ChainedError</a></td>
|
|||
|
<td class='docblock-short'>
|
|||
|
<p>This trait is implemented on all the errors generated by the <code>error_chain</code>
|
|||
|
macro.</p>
|
|||
|
|
|||
|
</td>
|
|||
|
</tr>
|
|||
|
<tr class=' module-item'>
|
|||
|
<td><a class="trait" href="trait.ExitCode.html"
|
|||
|
title='trait error_chain::ExitCode'>ExitCode</a></td>
|
|||
|
<td class='docblock-short'>
|
|||
|
<p>Represents a value that can be used as the exit status of the process.
|
|||
|
See <a href="macro.quick_main.html"><code>quick_main!</code></a>.</p>
|
|||
|
|
|||
|
</td>
|
|||
|
</tr></table></section>
|
|||
|
<section id='search' class="content hidden"></section>
|
|||
|
|
|||
|
<section class="footer"></section>
|
|||
|
|
|||
|
<aside id="help" class="hidden">
|
|||
|
<div>
|
|||
|
<h1 class="hidden">Help</h1>
|
|||
|
|
|||
|
<div class="shortcuts">
|
|||
|
<h2>Keyboard Shortcuts</h2>
|
|||
|
|
|||
|
<dl>
|
|||
|
<dt><kbd>?</kbd></dt>
|
|||
|
<dd>Show this help dialog</dd>
|
|||
|
<dt><kbd>S</kbd></dt>
|
|||
|
<dd>Focus the search field</dd>
|
|||
|
<dt><kbd>↑</kbd></dt>
|
|||
|
<dd>Move up in search results</dd>
|
|||
|
<dt><kbd>↓</kbd></dt>
|
|||
|
<dd>Move down in search results</dd>
|
|||
|
<dt><kbd>↹</kbd></dt>
|
|||
|
<dd>Switch tab</dd>
|
|||
|
<dt><kbd>⏎</kbd></dt>
|
|||
|
<dd>Go to active search result</dd>
|
|||
|
<dt><kbd>+</kbd></dt>
|
|||
|
<dd>Expand all sections</dd>
|
|||
|
<dt><kbd>-</kbd></dt>
|
|||
|
<dd>Collapse all sections</dd>
|
|||
|
</dl>
|
|||
|
</div>
|
|||
|
|
|||
|
<div class="infos">
|
|||
|
<h2>Search Tricks</h2>
|
|||
|
|
|||
|
<p>
|
|||
|
Prefix searches with a type followed by a colon (e.g.
|
|||
|
<code>fn:</code>) to restrict the search to a given type.
|
|||
|
</p>
|
|||
|
|
|||
|
<p>
|
|||
|
Accepted types are: <code>fn</code>, <code>mod</code>,
|
|||
|
<code>struct</code>, <code>enum</code>,
|
|||
|
<code>trait</code>, <code>type</code>, <code>macro</code>,
|
|||
|
and <code>const</code>.
|
|||
|
</p>
|
|||
|
|
|||
|
<p>
|
|||
|
Search functions by type signature (e.g.
|
|||
|
<code>vec -> usize</code> or <code>* -> vec</code>)
|
|||
|
</p>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</aside>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<script>
|
|||
|
window.rootPath = "../";
|
|||
|
window.currentCrate = "error_chain";
|
|||
|
</script>
|
|||
|
<script src="../main.js"></script>
|
|||
|
<script defer src="../search-index.js"></script>
|
|||
|
</body>
|
|||
|
</html>
|