{"id":1257,"date":"2022-01-17T17:49:44","date_gmt":"2022-01-17T23:49:44","guid":{"rendered":"http:\/\/blog.gwadej.org\/programmer_musings\/?p=1257"},"modified":"2025-09-07T14:04:57","modified_gmt":"2025-09-07T14:04:57","slug":"rust-error-handling-part-two","status":"publish","type":"post","link":"https:\/\/blog.gwadej.org\/programmer-musings\/2022\/01\/rust-error-handling-part-two\/","title":{"rendered":"Rust Error Handling, Part Two"},"content":{"rendered":"\n<p>In the previous <a href=\"\/programmer_musings\/2022\/01\/rust-error-handling-part-one\/\">post<\/a>, I covered a quick overview of error handling approaches in different languages. Then, I introduced Rust&#8217;s error handling using the <code>Result&lt;T, E&gt;<\/code> enum. This time we&#8217;ll look at how Rust&#8217;s approach improves on other techniques.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Compared to Error Returns<\/h2>\n\n\n\n<p>Returning a <code>Result&lt;T, E&gt;<\/code> from a function is very much like the error return approach used by earlier programming languages. Like simple error return values, error handling is pretty simple. All you need to do is check for the error return from each function that can return an error.<\/p>\n\n\n\n<p>Unlike the traditional error return values, though, <code>Result&lt;T, E&gt;<\/code> fixes some disadvantages. First of all, you cannot accidentally forget to check the error value. Two features of the language support this. One, you cannot use the error return as if it were the correct value, because you need to extract the value type in order to use it. If you try to extract the <code>T<\/code> from <code>Result&lt;T, E&gt;<\/code> when an error was returned, the code fails. Rust also prevents you from ignoring the error return from a function (accidentally or on purpose). Rust requires that you explicitly check the result, or explicitly discard it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ fails to compile, because the Result is not tested.\nfallible_func();\n\n\/\/ panics if the function returns an Err.\nlet v = fallible_func().unwrap();\n\n\/\/ fails to compile, because returns a Result\nlet v: T = fallible_func();<\/code><\/pre>\n\n\n\n<p>These two features prevent accidental mishandling of returned errors.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Compared to Exceptions<\/h2>\n\n\n\n<p>The main advantage to using exceptions for error handling is that the exception is automatically propagated, instead of being dropped if you don&#8217;t handle it. The problem with this approach is that it may not be obvious from the code when an error can be propagated.<\/p>\n\n\n\n<p>Rust handles this by explicitly returning the error from each function. Since the obvious code for detecting an error and re-returning it is rather straight-forward and repeatable, Rust supports the question mark operator (<code>?<\/code>) to simplify this common occurrence.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>let value = fallible_func()?;<\/code><\/pre>\n\n\n\n<p>Given that the <code>fallible_func()<\/code> method returns a <code>Result<\/code>, the <code>?<\/code> returns the value if the <code>Result<\/code> was <code>Ok<\/code>. If, on the other hand, the <code>Result<\/code> is an <code>Err<\/code>, <code>?<\/code> returns the error as a <code>Result<\/code> from the calling function. This gives much the same behavior as an exception, but the return to the calling function is explicit.<\/p>\n\n\n\n<p>One other feature of exceptions that is supported by Rust&#8217;s error handling is unconditional exit from the program. If an exception is not caught somewhere, it terminates the program. In Rust, you can do this explicitly one of two ways.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ An error return panics, terminating the program.\nfallible_func().unwrap();\n\n\/\/ An error return panics with the given message.\nfallible_func().expect(\"Shouldn't happen, panic!\");<\/code><\/pre>\n\n\n\n<p>Like all of the Rust error handling, the behavior is explicit enough that you can directly search for it in case of a panic that you did not expect.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Handling a Result<\/h2>\n\n\n\n<p>There are many approaches for handling a <code>Result<\/code>. Potentially the most obvious is pattern matching.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>match fallible_func() {\n    Ok(val) =&gt; use_value(val),\n    Err(e) =&gt; report_error(e)\n};<\/code><\/pre>\n\n\n\n<p>The <code>Ok(val)<\/code> branch covers handling the successful return of a value from <code>fallible_func()<\/code>. The <code>Err(e)<\/code> branch handles the error return from <code>fallible_func()<\/code>. Although easy to understand, this approach is a bit verbose. In some cases, it is the most appropriate.<\/p>\n\n\n\n<p>In the last section, I showed the usage <code>?<\/code> to automatically return the error.<\/p>\n\n\n\n<p>The Result type also supports a number of methods that simplify some relatively obvious ways you might like to deal with an error.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ return 42 if the function returned an error\nlet v = fallible_func().unwrap_or(42);\n\n\/\/ return the default value of the type on error\nlet v = fallible_func().unwrap_or_default();\n\n\/\/ execute make_value(e) on error\nlet v = fallible_func().unwrap_or_else(make_value);<\/code><\/pre>\n\n\n\n<p>These are all fairly obvious ways you might want to deal with a error, and they are directly supported by <code>Result<\/code>.<\/p>\n\n\n\n<p><code>Result<\/code> supports many other <a rel=\"noreferrer noopener\" href=\"https:\/\/doc.rust-lang.org\/std\/result\/enum.Result.html\" target=\"_blank\">methods<\/a>, including <code>map()<\/code> which converts the successful result, leaving an error alone and <code>map_err()<\/code> that converts the error result, leaving the success value alone.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>The <code>Result&lt;T, E&gt;<\/code> type in Rust makes error handling easier and more consistent than earlier error handling approaches. The default behavior of the <code>Resul<\/code>t&lt;T, E&gt; does not fail quietly and cannot easily be ignored. For a full discussion of Rust error handling, see the <a href=\"https:\/\/doc.rust-lang.org\/book\/ch09-00-error-handling.html\" target=\"_blank\" rel=\"noreferrer noopener\">Rust doc<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous post, I covered a quick overview of error handling approaches in different languages. Then, I introduced Rust&#8217;s error handling using the Result&lt;T, E&gt; enum. This time we&#8217;ll look at how Rust&#8217;s approach improves on other techniques. Compared to Error Returns Returning a Result&lt;T, E&gt; from a function is very much like the\u2026 <span class=\"read-more\"><a href=\"https:\/\/blog.gwadej.org\/programmer-musings\/2022\/01\/rust-error-handling-part-two\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[126,286,294],"_links":{"self":[{"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/posts\/1257"}],"collection":[{"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/comments?post=1257"}],"version-history":[{"count":1,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/posts\/1257\/revisions"}],"predecessor-version":[{"id":1375,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/posts\/1257\/revisions\/1375"}],"wp:attachment":[{"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/media?parent=1257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/categories?post=1257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.gwadej.org\/programmer-musings\/wp-json\/wp\/v2\/tags?post=1257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}