{"id":105157,"date":"2021-04-27T07:00:00","date_gmt":"2021-04-27T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=105157"},"modified":"2021-04-27T07:07:34","modified_gmt":"2021-04-27T14:07:34","slug":"20210427-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210427-00\/?p=105157","title":{"rendered":"C++ coroutines: How do I create a coroutine that terminates on an unhandled exception?"},"content":{"rendered":"<p>Last time, we saw that <a title=\"C++ coroutines: What does it mean when I declare my coroutine as noexcept?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210426-00\/?p=105153\"> declaring a coroutine as <code>noexcept<\/code> doesn&#8217;t do what you think<\/a>. The <code>noexcept<\/code> specific says that production of the coroutine does not throw an exception, but it says nothing about what happens during <i>execution<\/i> of the coroutine. If an exception occurs inside the coroutine, the promise&#8217;s <code>unhandled_<wbr \/>exception<\/code> method decides what happens.<\/p>\n<p>So what can you do if you really want your coroutine to terminate on unhandled exception?<\/p>\n<p>One way is to reimplement <code>noexcept<\/code> manually by catching all exceptions and terminating.<\/p>\n<pre>simple_task&lt;int&gt; GetValueAsync()\r\n{\r\n    try {\r\n        co_return LoadValue();\r\n    } catch (...) {\r\n        std::terminate();\r\n    }\r\n}\r\n<\/pre>\n<p>If an exception occurs in <code>Load\u00adValue()<\/code>, it is caught by the <code>catch (...)<\/code> and terminates the program.<\/p>\n<p>You can avoid a level of indentation by moving the <code>try<\/code> to function scope:<\/p>\n<pre>simple_task&lt;int&gt; GetValueAsync() <span style=\"color: blue;\">try<\/span>\r\n{\r\n    co_return LoadValue();\r\n} <span style=\"color: blue;\">catch (...) {\r\n    std::terminate();\r\n}<\/span>\r\n<\/pre>\n<p>This has the desired effect of terminating on unhandled exceptions, but it&#8217;s kind of awkward having to wrap the function like this, and it also gets awkward if you want to turn the behavior on for only certain sections of the code.<\/p>\n<p>The behavior of a coroutine in the case of an unhandled exception is left to the discretion of the coroutine promise. Some promises (like <code>winrt::<wbr \/>fire_<wbr \/>and_<wbr \/>forget<\/code>) terminate on unhandled exceptions. Others (like our <code>simple_task<\/code>) stow the exception and rethrow when the task is <code>co_await<\/code>ed. Perhaps there&#8217;s a way to configure the coroutine promise at runtime to alter its behavior. We&#8217;ll look at that next time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You need to get inside the coroutine.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-105157","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>You need to get inside the coroutine.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/105157","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=105157"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/105157\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=105157"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=105157"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=105157"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}