<!DOCTYPE HTML> <html lang="en" class="sidebar-visible no-js"> <head> <!-- Book generated using mdBook --> <meta charset="UTF-8"> <title>Controlling panics with std::panic - The Edition Guide</title> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="theme-color" content="#ffffff" /> <link rel="shortcut icon" href="../../favicon.png"> <link rel="stylesheet" href="../../css/variables.css"> <link rel="stylesheet" href="../../css/general.css"> <link rel="stylesheet" href="../../css/chrome.css"> <link rel="stylesheet" href="../../css/print.css" media="print"> <!-- Fonts --> <link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css"> <link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css"> <link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css"> <!-- Highlight.js Stylesheets --> <link rel="stylesheet" href="../../highlight.css"> <link rel="stylesheet" href="../../tomorrow-night.css"> <link rel="stylesheet" href="../../ayu-highlight.css"> <!-- Custom theme stylesheets --> </head> <body class="light"> <!-- Provide site root to javascript --> <script type="text/javascript"> var path_to_root = "../../"; var default_theme = "light"; </script> <!-- Work around some values being stored in localStorage wrapped in quotes --> <script type="text/javascript"> try { var theme = localStorage.getItem('mdbook-theme'); var sidebar = localStorage.getItem('mdbook-sidebar'); if (theme.startsWith('"') && theme.endsWith('"')) { localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1)); } if (sidebar.startsWith('"') && sidebar.endsWith('"')) { localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1)); } } catch (e) { } </script> <!-- Set the theme before any content is loaded, prevents flash --> <script type="text/javascript"> var theme; try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { } if (theme === null || theme === undefined) { theme = default_theme; } document.body.className = theme; document.querySelector('html').className = theme + ' js'; </script> <!-- Hide / unhide sidebar before it is displayed --> <script type="text/javascript"> var html = document.querySelector('html'); var sidebar = 'hidden'; if (document.body.clientWidth >= 1080) { try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { } sidebar = sidebar || 'visible'; } html.classList.remove('sidebar-visible'); html.classList.add("sidebar-" + sidebar); </script> <nav id="sidebar" class="sidebar" aria-label="Table of contents"> <ol class="chapter"><li class="affix"><a href="../../introduction.html">Introduction</a></li><li><a href="../../editions/index.html"><strong aria-hidden="true">1.</strong> What are editions?</a></li><li><ol class="section"><li><a href="../../editions/creating-a-new-project.html"><strong aria-hidden="true">1.1.</strong> Creating a new project</a></li><li><a href="../../editions/transitioning-an-existing-project-to-a-new-edition.html"><strong aria-hidden="true">1.2.</strong> Transitioning an existing project to a new edition</a></li></ol></li><li><a href="../../rust-2015/index.html"><strong aria-hidden="true">2.</strong> Rust 2015</a></li><li><a href="../../rust-2018/index.html"><strong aria-hidden="true">3.</strong> Rust 2018</a></li><li><ol class="section"><li><a href="../../rust-2018/edition-changes.html"><strong aria-hidden="true">3.1.</strong> 2018-Specific Changes</a></li><li><a href="../../rust-2018/module-system/index.html"><strong aria-hidden="true">3.2.</strong> Module system</a></li><li><ol class="section"><li><a href="../../rust-2018/module-system/raw-identifiers.html"><strong aria-hidden="true">3.2.1.</strong> Raw identifiers</a></li><li><a href="../../rust-2018/module-system/path-clarity.html"><strong aria-hidden="true">3.2.2.</strong> Path clarity</a></li><li><a href="../../rust-2018/module-system/more-visibility-modifiers.html"><strong aria-hidden="true">3.2.3.</strong> More visibility modifiers</a></li><li><a href="../../rust-2018/module-system/nested-imports-with-use.html"><strong aria-hidden="true">3.2.4.</strong> Nested imports with use</a></li></ol></li><li><a href="../../rust-2018/error-handling-and-panics/index.html"><strong aria-hidden="true">3.3.</strong> Error handling and panics</a></li><li><ol class="section"><li><a href="../../rust-2018/error-handling-and-panics/the-question-mark-operator-for-easier-error-handling.html"><strong aria-hidden="true">3.3.1.</strong> The ? operator for easier error handling</a></li><li><a href="../../rust-2018/error-handling-and-panics/question-mark-in-main-and-tests.html"><strong aria-hidden="true">3.3.2.</strong> ? in main and tests</a></li><li><a href="../../rust-2018/error-handling-and-panics/controlling-panics-with-std-panic.html" class="active"><strong aria-hidden="true">3.3.3.</strong> Controlling panics with std::panic</a></li><li><a href="../../rust-2018/error-handling-and-panics/aborting-on-panic.html"><strong aria-hidden="true">3.3.4.</strong> Aborting on panic</a></li></ol></li><li><a href="../../rust-2018/control-flow/index.html"><strong aria-hidden="true">3.4.</strong> Control flow</a></li><li><ol class="section"><li><a href="../../rust-2018/control-flow/loops-can-break-with-a-value.html"><strong aria-hidden="true">3.4.1.</strong> Loops can break with a value</a></li><li><a href="../../rust-2018/control-flow/async-await-for-easier-concurrency.html"><strong aria-hidden="true">3.4.2.</strong> async/await for easier concurrency</a></li></ol></li><li><a href="../../rust-2018/trait-system/index.html"><strong aria-hidden="true">3.5.</strong> Trait system</a></li><li><ol class="section"><li><a href="../../rust-2018/trait-system/impl-trait-for-returning-complex-types-with-ease.html"><strong aria-hidden="true">3.5.1.</strong> impl Trait for returning complex types with ease</a></li><li><a href="../../rust-2018/trait-system/dyn-trait-for-trait-objects.html"><strong aria-hidden="true">3.5.2.</strong> dyn Trait for trait objects</a></li><li><a href="../../rust-2018/trait-system/more-container-types-support-trait-objects.html"><strong aria-hidden="true">3.5.3.</strong> More container types support trait objects</a></li><li><a href="../../rust-2018/trait-system/associated-constants.html"><strong aria-hidden="true">3.5.4.</strong> Associated constants</a></li><li><a href="../../rust-2018/trait-system/no-anon-params.html"><strong aria-hidden="true">3.5.5.</strong> No more anonymous parameters</a></li></ol></li><li><a href="../../rust-2018/slice-patterns.html"><strong aria-hidden="true">3.6.</strong> Slice patterns</a></li><li><a href="../../rust-2018/ownership-and-lifetimes/index.html"><strong aria-hidden="true">3.7.</strong> Ownership and lifetimes</a></li><li><ol class="section"><li><a href="../../rust-2018/ownership-and-lifetimes/non-lexical-lifetimes.html"><strong aria-hidden="true">3.7.1.</strong> Non-lexical lifetimes</a></li><li><a href="../../rust-2018/ownership-and-lifetimes/default-match-bindings.html"><strong aria-hidden="true">3.7.2.</strong> Default match bindings</a></li><li><a href="../../rust-2018/ownership-and-lifetimes/the-anonymous-lifetime.html"><strong aria-hidden="true">3.7.3.</strong> '_, the anonymous lifetime</a></li><li><a href="../../rust-2018/ownership-and-lifetimes/lifetime-elision-in-impl.html"><strong aria-hidden="true">3.7.4.</strong> Lifetime elision in impl</a></li><li><a href="../../rust-2018/ownership-and-lifetimes/inference-in-structs.html"><strong aria-hidden="true">3.7.5.</strong> T: 'a inference in structs</a></li><li><a href="../../rust-2018/ownership-and-lifetimes/simpler-lifetimes-in-static-and-const.html"><strong aria-hidden="true">3.7.6.</strong> Simpler lifetimes in static and const</a></li></ol></li><li><a href="../../rust-2018/data-types/index.html"><strong aria-hidden="true">3.8.</strong> Data types</a></li><li><ol class="section"><li><a href="../../rust-2018/data-types/field-init-shorthand.html"><strong aria-hidden="true">3.8.1.</strong> Field init shorthand</a></li><li><a href="../../rust-2018/data-types/inclusive-ranges.html"><strong aria-hidden="true">3.8.2.</strong> ..= for inclusive ranges</a></li><li><a href="../../rust-2018/data-types/128-bit-integers.html"><strong aria-hidden="true">3.8.3.</strong> 128 bit integers</a></li><li><a href="../../rust-2018/data-types/operator-equals-are-now-implementable.html"><strong aria-hidden="true">3.8.4.</strong> "Operator-equals" are now implementable</a></li><li><a href="../../rust-2018/data-types/union-for-an-unsafe-form-of-enum.html"><strong aria-hidden="true">3.8.5.</strong> union for an unsafe form of enum</a></li><li><a href="../../rust-2018/data-types/choosing-alignment-with-the-repr-attribute.html"><strong aria-hidden="true">3.8.6.</strong> Choosing alignment with the repr attribute</a></li></ol></li><li><a href="../../rust-2018/simd-for-faster-computing.html"><strong aria-hidden="true">3.9.</strong> SIMD for faster computing</a></li><li><a href="../../rust-2018/macros/index.html"><strong aria-hidden="true">3.10.</strong> Macros</a></li><li><ol class="section"><li><a href="../../rust-2018/macros/custom-derive.html"><strong aria-hidden="true">3.10.1.</strong> Custom Derive</a></li><li><a href="../../rust-2018/macros/macro-changes.html"><strong aria-hidden="true">3.10.2.</strong> Macro changes</a></li><li><a href="../../rust-2018/macros/at-most-once.html"><strong aria-hidden="true">3.10.3.</strong> At most one repetition</a></li></ol></li><li><a href="../../rust-2018/the-compiler/index.html"><strong aria-hidden="true">3.11.</strong> The compiler</a></li><li><ol class="section"><li><a href="../../rust-2018/the-compiler/improved-error-messages.html"><strong aria-hidden="true">3.11.1.</strong> Improved error messages</a></li><li><a href="../../rust-2018/the-compiler/incremental-compilation-for-faster-compiles.html"><strong aria-hidden="true">3.11.2.</strong> Incremental Compilation for faster compiles</a></li><li><a href="../../rust-2018/the-compiler/an-attribute-for-deprecation.html"><strong aria-hidden="true">3.11.3.</strong> An attribute for deprecation</a></li></ol></li><li><a href="../../rust-2018/rustup-for-managing-rust-versions.html"><strong aria-hidden="true">3.12.</strong> Rustup for managing Rust versions</a></li><li><a href="../../rust-2018/cargo-and-crates-io/index.html"><strong aria-hidden="true">3.13.</strong> Cargo and crates.io</a></li><li><ol class="section"><li><a href="../../rust-2018/cargo-and-crates-io/cargo-check-for-faster-checking.html"><strong aria-hidden="true">3.13.1.</strong> cargo check for faster checking</a></li><li><a href="../../rust-2018/cargo-and-crates-io/cargo-install-for-easy-installation-of-tools.html"><strong aria-hidden="true">3.13.2.</strong> cargo install for easy installation of tools</a></li><li><a href="../../rust-2018/cargo-and-crates-io/cargo-new-defaults-to-a-binary-project.html"><strong aria-hidden="true">3.13.3.</strong> cargo new defaults to a binary project</a></li><li><a href="../../rust-2018/cargo-and-crates-io/cargo-rustc-for-passing-arbitrary-flags-to-rustc.html"><strong aria-hidden="true">3.13.4.</strong> cargo rustc for passing arbitrary flags to rustc</a></li><li><a href="../../rust-2018/cargo-and-crates-io/cargo-workspaces-for-multi-package-projects.html"><strong aria-hidden="true">3.13.5.</strong> Cargo workspaces for multi-package projects</a></li><li><a href="../../rust-2018/cargo-and-crates-io/multi-file-examples.html"><strong aria-hidden="true">3.13.6.</strong> Multi-file examples</a></li><li><a href="../../rust-2018/cargo-and-crates-io/replacing-dependencies-with-patch.html"><strong aria-hidden="true">3.13.7.</strong> Replacing dependencies with patch</a></li><li><a href="../../rust-2018/cargo-and-crates-io/cargo-can-use-a-local-registry-replacement.html"><strong aria-hidden="true">3.13.8.</strong> Cargo can use a local registry replacement</a></li><li><a href="../../rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html"><strong aria-hidden="true">3.13.9.</strong> Crates.io disallows wildcard dependencies</a></li></ol></li><li><a href="../../rust-2018/documentation/index.html"><strong aria-hidden="true">3.14.</strong> Documentation</a></li><li><ol class="section"><li><a href="../../rust-2018/documentation/new-editions-of-the-book.html"><strong aria-hidden="true">3.14.1.</strong> New editions of the "the book"</a></li><li><a href="../../rust-2018/documentation/the-rust-bookshelf.html"><strong aria-hidden="true">3.14.2.</strong> The Rust Bookshelf</a></li><li><a href="../../rust-2018/documentation/the-rustonomicon.html"><strong aria-hidden="true">3.14.3.</strong> The Rustonomicon</a></li><li><a href="../../rust-2018/documentation/std-os-has-documentation-for-all-platforms.html"><strong aria-hidden="true">3.14.4.</strong> Full documentation for std::os</a></li></ol></li><li><a href="../../rust-2018/rustdoc/index.html"><strong aria-hidden="true">3.15.</strong> rustdoc</a></li><li><ol class="section"><li><a href="../../rust-2018/rustdoc/documentation-tests-can-now-compile-fail.html"><strong aria-hidden="true">3.15.1.</strong> Documentation tests can now compile-fail</a></li><li><a href="../../rust-2018/rustdoc/rustdoc-uses-commonmark.html"><strong aria-hidden="true">3.15.2.</strong> Rustdoc uses CommonMark</a></li></ol></li><li><a href="../../rust-2018/platform-and-target-support/index.html"><strong aria-hidden="true">3.16.</strong> Platform and target support</a></li><li><ol class="section"><li><a href="../../rust-2018/platform-and-target-support/libcore-for-low-level-rust.html"><strong aria-hidden="true">3.16.1.</strong> libcore for low-level Rust</a></li><li><a href="../../rust-2018/platform-and-target-support/webassembly-support.html"><strong aria-hidden="true">3.16.2.</strong> WebAssembly support</a></li><li><a href="../../rust-2018/platform-and-target-support/global-allocators.html"><strong aria-hidden="true">3.16.3.</strong> Global allocators</a></li><li><a href="../../rust-2018/platform-and-target-support/msvc-toolchain-support.html"><strong aria-hidden="true">3.16.4.</strong> MSVC toolchain support</a></li><li><a href="../../rust-2018/platform-and-target-support/musl-support-for-fully-static-binaries.html"><strong aria-hidden="true">3.16.5.</strong> MUSL support for fully static binaries</a></li><li><a href="../../rust-2018/platform-and-target-support/cdylib-crates-for-c-interoperability.html"><strong aria-hidden="true">3.16.6.</strong> cdylib crates for C interoperability</a></li></ol></li></ol></li></ol> </nav> <div id="page-wrapper" class="page-wrapper"> <div class="page"> <div id="menu-bar" class="menu-bar"> <div id="menu-bar-sticky-container"> <div class="left-buttons"> <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar"> <i class="fa fa-bars"></i> </button> <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list"> <i class="fa fa-paint-brush"></i> </button> <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu"> <li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li> <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li> <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li> <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li> <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li> </ul> <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar"> <i class="fa fa-search"></i> </button> </div> <h1 class="menu-title">The Edition Guide</h1> <div class="right-buttons"> <a href="../../print.html" title="Print this book" aria-label="Print this book"> <i id="print-button" class="fa fa-print"></i> </a> </div> </div> </div> <div id="search-wrapper" class="hidden"> <form id="searchbar-outer" class="searchbar-outer"> <input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header"> </form> <div id="searchresults-outer" class="searchresults-outer hidden"> <div id="searchresults-header" class="searchresults-header"></div> <ul id="searchresults"> </ul> </div> </div> <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM --> <script type="text/javascript"> document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible'); document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible'); Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) { link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1); }); </script> <div id="content" class="content"> <main> <a class="header" href="#controlling-panics-with-stdpanic" id="controlling-panics-with-stdpanic"><h1>Controlling panics with <code>std::panic</code></h1></a> <p><img src="https://img.shields.io/badge/Minimum%20Rust%20Version-1.9-brightgreen.svg" alt="Minimum Rust version: 1.9" /></p> <p>There is a <code>std::panic</code> module, which includes methods for halting the unwinding process started by a panic:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { use std::panic; let result = panic::catch_unwind(|| { println!("hello!"); }); assert!(result.is_ok()); let result = panic::catch_unwind(|| { panic!("oh no!"); }); assert!(result.is_err()); #}</code></pre></pre> <p>In general, Rust distinguishes between two ways that an operation can fail:</p> <ul> <li>Due to an <em>expected problem</em>, like a file not being found.</li> <li>Due to an <em>unexpected problem</em>, like an index being out of bounds for an array.</li> </ul> <p>Expected problems usually arise from conditions that are outside of your control; robust code should be prepared for anything its environment might throw at it. In Rust, expected problems are handled via <a href="http://doc.rust-lang.org/std/result/index.html">the <code>Result</code> type</a>, which allows a function to return information about the problem to its caller, which can then handle the error in a fine-grained way.</p> <p>Unexpected problems are <em>bugs</em>: they arise due to a contract or assertion being violated. Since they are unexpected, it doesn't make sense to handle them in a fine-grained way. Instead, Rust employs a "fail fast" approach by <em>panicking</em>, which by default unwinds the stack (running destructors but no other code) of the thread which discovered the error. Other threads continue running, but will discover the panic any time they try to communicate with the panicked thread (whether through channels or shared memory). Panics thus abort execution up to some "isolation boundary", with code on the other side of the boundary still able to run, and perhaps to "recover" from the panic in some very coarse-grained way. A server, for example, does not necessarily need to go down just because of an assertion failure in one of its threads.</p> <p>It's also worth noting that programs may choose to <em>abort</em> instead of unwind, and so catching panics may not work. If your code relies on <code>catch_unwind</code>, you should add this to your Cargo.toml:</p> <pre><code class="language-toml">[profile.debug] panic = "unwind" [profile.release] panic = "unwind" </code></pre> <p>If any of your users choose to abort, they'll get a compile-time failure.</p> <p>The <code>catch_unwind</code> API offers a way to introduce new isolation boundaries <em>within a thread</em>. There are a couple of key motivating examples:</p> <ul> <li>Embedding Rust in other languages</li> <li>Abstractions that manage threads</li> <li>Test frameworks, because tests may panic and you don't want that to kill the test runner</li> </ul> <p>For the first case, unwinding across a language boundary is undefined behavior, and often leads to segfaults in practice. Allowing panics to be caught means that you can safely expose Rust code via a C API, and translate unwinding into an error on the C side.</p> <p>For the second case, consider a threadpool library. If a thread in the pool panics, you generally don't want to kill the thread itself, but rather catch the panic and communicate it to the client of the pool. The <code>catch_unwind</code> API is paired with <code>resume_unwind</code>, which can then be used to restart the panicking process on the client of the pool, where it belongs.</p> <p>In both cases, you're introducing a new isolation boundary within a thread, and then translating the panic into some other form of error elsewhere.</p> </main> <nav class="nav-wrapper" aria-label="Page navigation"> <!-- Mobile navigation buttons --> <a rel="prev" href="../../rust-2018/error-handling-and-panics/question-mark-in-main-and-tests.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <i class="fa fa-angle-left"></i> </a> <a rel="next" href="../../rust-2018/error-handling-and-panics/aborting-on-panic.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <i class="fa fa-angle-right"></i> </a> <div style="clear: both"></div> </nav> </div> </div> <nav class="nav-wide-wrapper" aria-label="Page navigation"> <a href="../../rust-2018/error-handling-and-panics/question-mark-in-main-and-tests.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <i class="fa fa-angle-left"></i> </a> <a href="../../rust-2018/error-handling-and-panics/aborting-on-panic.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <i class="fa fa-angle-right"></i> </a> </nav> </div> <script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script> <script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script> <script src="../../searcher.js" type="text/javascript" charset="utf-8"></script> <script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script> <script src="../../highlight.js" type="text/javascript" charset="utf-8"></script> <script src="../../book.js" type="text/javascript" charset="utf-8"></script> <!-- Custom JS scripts --> </body> </html>