Skip to content

Commit abbd214

Browse files
committed
deploy: d2a95a7
1 parent 1d748b9 commit abbd214

File tree

4 files changed

+78
-86
lines changed

4 files changed

+78
-86
lines changed

print.html

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -501,18 +501,17 @@ <h2 id="wrapping-up-1"><a class="header" href="#wrapping-up-1">Wrapping up</a></
501501
</aside>
502502
<div style="break-before: page; page-break-before: always;"></div><h1 id="nicer-error-reporting"><a class="header" href="#nicer-error-reporting">Nicer error reporting</a></h1>
503503
<p>We all can do nothing but accept the fact that errors will occur.
504-
And in contrast to many other languages,
504+
In contrast to many other languages,
505505
it’s very hard not to notice and deal with this reality
506-
when using Rust:
507-
As it doesn’t have exceptions,
508-
all possible error states are often encoded in the return types of functions.</p>
506+
when using Rust because it doesn’t have exceptions.
507+
All possible error states are often encoded in the return types of functions.</p>
509508
<h2 id="results"><a class="header" href="#results">Results</a></h2>
510509
<p>A function like <a href="https://doc.rust-lang.org/1.39.0/std/fs/fn.read_to_string.html"><code>read_to_string</code></a> doesn’t return a string.
511510
Instead, it returns a <a href="https://doc.rust-lang.org/1.39.0/std/result/index.html"><code>Result</code></a>
512511
that contains either
513512
a <code>String</code>
514-
or an error of some type
515-
(in this case <a href="https://doc.rust-lang.org/1.39.0/std/io/type.Result.html"><code>std::io::Error</code></a>).</p>
513+
or an error of some type.
514+
In this case, <a href="https://doc.rust-lang.org/1.39.0/std/io/type.Result.html"><code>std::io::Error</code></a>.</p>
516515
<p>How do you know which it is?
517516
Since <code>Result</code> is an <code>enum</code>,
518517
you can use <code>match</code> to check which variant it is:</p>
@@ -529,15 +528,15 @@ <h2 id="results"><a class="header" href="#results">Results</a></h2>
529528
<aside>
530529
<p><strong>Note:</strong>
531530
Not sure what enums are or how they work in Rust?
532-
<a href="https://doc.rust-lang.org/1.39.0/book/ch06-00-enums.html">Check this chapter of the Rust book</a>
531+
<a href="https://doc.rust-lang.org/1.39.0/book/ch06-00-enums.html">Check out this chapter of the Rust book</a>
533532
to get up to speed.</p>
534533
</aside>
535534
<h2 id="unwrapping"><a class="header" href="#unwrapping">Unwrapping</a></h2>
536535
<p>Now, we were able to access the content of the file,
537536
but we can’t really do anything with it after the <code>match</code> block.
538-
For this, we’ll need to somehow deal with the error case.
539-
The challenge is that all arms of a <code>match</code> block need to return something of the same type.
540-
But there’s a neat trick to get around that:</p>
537+
For this, we’ll need to deal with the error case.
538+
While it’s a challenge that all arms of a <code>match</code> block need to return something of the same type,
539+
there’s a neat trick to get around that:</p>
541540
<pre><pre class="playground"><code class="language-rust no_run">
542541
<span class="boring">#![allow(unused)]
543542
</span><span class="boring">fn main() {
@@ -549,15 +548,14 @@ <h2 id="unwrapping"><a class="header" href="#unwrapping">Unwrapping</a></h2>
549548
println!(&quot;file content: {}&quot;, content);
550549
<span class="boring">}
551550
</span></code></pre></pre>
552-
<p>We can use the String in <code>content</code> after the match block.
553-
If <code>result</code> were an error, the String wouldn’t exist.
554-
But since the program would exit before it ever reached a point where we use <code>content</code>,
555-
it’s fine.</p>
551+
<p>We can use the String in <code>content</code> after the match block, but
552+
if <code>result</code> were an error, the String wouldn’t exist.
553+
That’s fine because the program would exit before it ever reached a point where we use <code>content</code>.</p>
556554
<p>This may seem drastic,
557555
but it’s very convenient.
558556
If your program needs to read that file and can’t do anything if the file doesn’t exist,
559557
exiting is a valid strategy.
560-
There’s even a shortcut method on <code>Result</code>s, called <code>unwrap</code>:</p>
558+
There’s even a shortcut method on <a href="https://doc.rust-lang.org/1.39.0/std/result/index.html"><code>Result</code></a> called <code>unwrap</code>:</p>
561559
<pre><pre class="playground"><code class="language-rust no_run">
562560
<span class="boring">#![allow(unused)]
563561
</span><span class="boring">fn main() {
@@ -566,7 +564,7 @@ <h2 id="unwrapping"><a class="header" href="#unwrapping">Unwrapping</a></h2>
566564
</span></code></pre></pre>
567565
<h2 id="no-need-to-panic"><a class="header" href="#no-need-to-panic">No need to panic</a></h2>
568566
<p>Of course, aborting the program is not the only way to deal with errors.
569-
Instead of the <code>panic!</code>, we can also easily write <code>return</code>:</p>
567+
Instead of using <code>panic!</code>, we can just use <code>return</code>:</p>
570568
<pre><pre class="playground"><code class="language-rust no_run"><span class="boring">fn main() -&gt; Result&lt;(), Box&lt;dyn std::error::Error&gt;&gt; {
571569
</span>let result = std::fs::read_to_string(&quot;test.txt&quot;);
572570
let content = match result {
@@ -576,8 +574,8 @@ <h2 id="no-need-to-panic"><a class="header" href="#no-need-to-panic">No need to
576574
<span class="boring">Ok(())
577575
</span><span class="boring">}
578576
</span></code></pre></pre>
579-
<p>This, however changes the return type our function needs.
580-
Indeed, there was something hidden in our examples all this time:
577+
<p>However, this changes the return type in our function.
578+
There was something hidden in our examples all this time:
581579
The function signature this code lives in.
582580
And in this last example with <code>return</code>,
583581
it becomes important.
@@ -595,14 +593,14 @@ <h2 id="no-need-to-panic"><a class="header" href="#no-need-to-panic">No need to
595593
<p>Our return type is a <code>Result</code>!
596594
This is why we can write <code>return Err(error);</code> in the second match arm.
597595
See how there is an <code>Ok(())</code> at the bottom?
598-
It’s the default return value of the function and means
596+
It’s the default return value of the function and means:
599597
“Result is okay, and has no content”.</p>
600598
<aside>
601599
<p><strong>Note:</strong>
602600
Why is this not written as <code>return Ok(());</code>?
603601
It easily could be – this is totally valid as well.
604602
The last expression of any block in Rust is its return value,
605-
and it is customary to omit needless <code>return</code>s.</p>
603+
and it is customary to omit a needless <code>return</code>.</p>
606604
</aside>
607605
<h2 id="question-mark"><a class="header" href="#question-mark">Question Mark</a></h2>
608606
<p>Just like calling <code>.unwrap()</code> is a shortcut
@@ -626,29 +624,29 @@ <h2 id="question-mark"><a class="header" href="#question-mark">Question Mark</a>
626624
There are a few more things happening here
627625
that are not required to understand to work with this.
628626
For example,
629-
the error type in our <code>main</code> function is <code>Box&lt;dyn std::error::Error&gt;</code>.
630-
But we’ve seen above that <code>read_to_string</code> returns a <a href="https://doc.rust-lang.org/1.39.0/std/io/type.Result.html"><code>std::io::Error</code></a>.
627+
the error type in our <code>main</code> function is <code>Box&lt;dyn std::error::Error&gt;</code>,
628+
but we’ve seen above that <code>read_to_string</code> returns a <a href="https://doc.rust-lang.org/1.39.0/std/io/type.Result.html"><code>std::io::Error</code></a>.
631629
This works because <code>?</code> expands to code that <em>converts</em> error types.</p>
632630
<p><code>Box&lt;dyn std::error::Error&gt;</code> is also an interesting type.
633631
It’s a <code>Box</code> that can contain <em>any</em> type
634632
that implements the standard <a href="https://doc.rust-lang.org/1.39.0/std/error/trait.Error.html"><code>Error</code></a> trait.
635-
This means that basically all errors can be put into this box,
636-
so we can use <code>?</code> on all of the usual functions that return <code>Result</code>s.</p>
633+
This means that all errors can be put into this box,
634+
and we can use <code>?</code> on all of the usual functions that return a <code>Result</code>.</p>
637635
</aside>
638636
<h2 id="providing-context"><a class="header" href="#providing-context">Providing Context</a></h2>
639637
<p>The errors you get when using <code>?</code> in your <code>main</code> function are okay,
640638
but they are not great.
641-
For example:
642-
When you run <code>std::fs::read_to_string(&quot;test.txt&quot;)?</code>
643-
but the file <code>test.txt</code> doesn’t exist,
639+
For example,
640+
when you run <code>std::fs::read_to_string(&quot;test.txt&quot;)?</code>
641+
and the file <code>test.txt</code> doesn’t exist,
644642
you get this output:</p>
645643
<pre><code class="language-text">Error: Os { code: 2, kind: NotFound, message: &quot;No such file or directory&quot; }
646644
</code></pre>
647-
<p>In cases where your code doesn’t literally contain the file name,
648-
it would be very hard to tell which file was <code>NotFound</code>.
645+
<p>In cases where your code doesn’t actually contain the file name,
646+
it would be hard to tell which file was <code>NotFound</code>.
649647
There are multiple ways to deal with this.</p>
650-
<p>For example, we can create our own error type,
651-
and then use that to build a custom error message:</p>
648+
<p>For one, we can create our own error type
649+
and use that to build a custom error message:</p>
652650
<pre><code class="language-rust ignore">#[derive(Debug)]
653651
struct CustomError(String);
654652

@@ -660,25 +658,23 @@ <h2 id="providing-context"><a class="header" href="#providing-context">Providing
660658
Ok(())
661659
}
662660
</code></pre>
663-
<p>Now,
664-
running this we’ll get our custom error message:</p>
661+
<p>Running this, we’ll get our custom error message:</p>
665662
<pre><code class="language-text">Error: CustomError(&quot;Error reading `test.txt`: No such file or directory (os error 2)&quot;)
666663
</code></pre>
667664
<p>Not very pretty,
668-
but we can easily adapt the debug output for our type later on.</p>
669-
<p>This pattern is in fact very common.
670-
It has one problem, though:
665+
but we can adapt the debug output for our type later on.</p>
666+
<p>This pattern is very common.
667+
It has one problem though:
671668
We don’t store the original error,
672669
only its string representation.
673-
The often used <a href="https://docs.rs/anyhow"><code>anyhow</code></a> library has a neat solution for that:
674-
similar to our <code>CustomError</code> type,
675-
its <a href="https://docs.rs/anyhow/1.0/anyhow/trait.Context.html"><code>Context</code></a> trait can be used to add a description.
676-
Additionally, it also keeps the original error,
677-
so we get a “chain” of error messages pointing out the root cause.</p>
670+
The popular <a href="https://docs.rs/anyhow"><code>anyhow</code></a> library has a neat solution for that:
671+
Its <a href="https://docs.rs/anyhow/1.0/anyhow/trait.Context.html"><code>Context</code></a> trait can be used to add a description similar to our <code>CustomError</code> type.
672+
Additionally, it keeps the original error,
673+
so we get a “chain” of error messages pointing to the root cause.</p>
678674
<p>Let’s first import the <code>anyhow</code> crate by adding
679675
<code>anyhow = &quot;1.0&quot;</code> to the <code>[dependencies]</code> section
680676
of our <code>Cargo.toml</code> file.</p>
681-
<p>The full example will then look like this:</p>
677+
<p>The full example will look like this:</p>
682678
<pre><code class="language-rust ignore">use anyhow::{Context, Result};
683679

684680
fn main() -&gt; Result&lt;()&gt; {

searchindex.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

searchindex.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)