{"id":105448,"date":"2021-07-16T07:00:00","date_gmt":"2021-07-16T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=105448"},"modified":"2021-07-16T08:08:14","modified_gmt":"2021-07-16T15:08:14","slug":"20210716-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210716-00\/?p=105448","title":{"rendered":"What&#8217;s the difference between throwing a <CODE>winrt::hresult_error<\/CODE> and using <CODE>winrt::throw_hresult<\/CODE>?"},"content":{"rendered":"<p>There are two ways to throw an exception in C++\/WinRT. You can throw the exception object directly:<\/p>\n<pre>throw winrt::hresult_invalid_argument();\r\nthrow winrt::hresult_error(D3DERR_DEVICELOST);\r\n<\/pre>\n<p>Or you can use the <code>throw_hresult<\/code> function.<\/p>\n<pre>winrt::throw_hresult(E_INVALIDARG);\r\nwinrt::throw_hresult(D3DERR_DEVICELOST);\r\n<\/pre>\n<p>What&#8217;s the difference?<\/p>\n<p>If you look at the code for the <code>throw_hresult<\/code> function, you&#8217;ll see that it eventually throws the underlying exception object, but it constructs the exception object with the <code>take_<wbr \/>ownership_<wbr \/>from_<wbr \/>abi<\/code> parameter. So the real question is &#8220;What does the <code>take_<wbr \/>ownership_<wbr \/>from_<wbr \/>abi<\/code> parameter do?&#8221;<\/p>\n<p>The <code>take_<wbr \/>ownership_<wbr \/>from_<wbr \/>abi<\/code> parameter means that this exception is taking over the error context from the existing ABI error context. The error context is what is used by error reporting tools and debuggers to show the root cause of the error.<\/p>\n<p>So it boils down to this:<\/p>\n<ul>\n<li>If this error was detected by your code, then you want the debugger and other error reporting tools to point to your code as the source of the error, and you should use <code>throw winrt::hresult_error<\/code> or a specific derived exception type if applicable, such as <code>hresult_<wbr \/>invalid_<wbr \/>argument<\/code>.<\/li>\n<li>If you are propagating an error received by another component, then you want the debugger and other error reporting tools to direct the developer to the component from which you received the error. In that case, you should use <code>winrt::throw_hresult<\/code>.<\/li>\n<\/ul>\n<p>Note that in the second case (propagation), the component you received the error from could itself be propagating an error from yet another component. As long as everybody propagates the error context along with the error, the debugging tools will point at the code that originated the error.\u00b9<\/p>\n<p>\u00b9 The intermediate components are also reported, so you can also follow how the error traveled from the originator to the final destination, but the origination usually gives you the best information about what went wrong.\u00b2<\/p>\n<p>\u00b2 <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/api\/restrictederrorinfo\/\"> Propagating and transforming error context<\/a> brings us full circle to the very early days of COM <a title=\"Why does HRESULT begin with H when it\u2019s not a handle to anything?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20180117-00\/?p=97815\"> when HRESULT was a handle to an error object<\/a>. The old new thing has become the new old thing.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It affects the error origination.<\/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-105448","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It affects the error origination.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/105448","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=105448"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/105448\/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=105448"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=105448"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=105448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}