{"id":765,"date":"2019-04-25T19:20:09","date_gmt":"2019-04-25T19:20:09","guid":{"rendered":"http:\/\/www.smart-bricks.net\/?p=765"},"modified":"2019-04-28T22:23:11","modified_gmt":"2019-04-28T22:23:11","slug":"c-futures-deferred-error-handling","status":"publish","type":"post","link":"http:\/\/www.smart-bricks.net\/index.php\/2019\/04\/25\/c-futures-deferred-error-handling\/","title":{"rendered":"C# Futures: Deferred Error Handling"},"content":{"rendered":"\n<p>When writing robust software, there is often a need to  perform a series of retrievable operations. In order to make the system  robust, each operation in the series can be coded so it is independent  of the status of the previous operation. As a concrete example, consider  a file processing pipeline.<\/p>\n\n\n\n<p>The first step in the pipeline may be to poll a file server and \ndownload any newly detected files. The next step would be to parse those\n files and convert them into a more usable format. A third step would be\n to import the converted files into a database for further processing.<\/p>\n\n\n\n<p>If the first step fails after downloading some of the files, the \napplication as a whole shouldn\u2019t abort. Rather, it should go onto the \nnext step and start parsing the files that were successfully downloaded.\n This is acceptable because the missed files can simply be picked up \nduring the next cycle.<\/p>\n\n\n\n<p>To implement this pattern in C# one usually has to use a series of try-catch blocks.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>try\n{\n    DownloadFiles();\n}\ncatch (Exception ex)\n{\n    \/\/log errors\n}\ntry\n{\n    ParseAndConvertFiles();\n}\ncatch (Exception ex)\n{\n    \/\/log errors\n}\ntry\n{\n    ImportFiles();\n}\ncatch (Exception ex)\n{\n    \/\/log errors\n}\n<\/code><\/pre>\n\n\n\n<p>With the Deferred Error Handling proposal, much of this boilerplate code can be removed.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#exception mode deferred\nDownloadFiles();\nParseAndConvertFiles();\nImportFiles();\nif (Exception.LastException != null)\n{\n    \/\/log errors\n    Exception.ClearLastException();\n}\n#exception mode structured\n<\/code><\/pre>\n\n\n\n<p>In order to use deferred error handling, a new compiler directive \ncalled \u201cexception mode\u201d is used. This switches the current function \nbetween structured exception handling and the new deferred mode.<\/p>\n\n\n\n<p>When using the deferred mode, the Exception.LastException property \ncan be used to determine if an error has occurred. This stores only the \nmost recent error, so if multiple errors occurred, all but the last will\n be lost.<\/p>\n\n\n\n<p>This has caused some concern, as it would mean one should check \nLastException after each line, which would be contrary to the goal of \nreducing the amount of code needed.<\/p>\n\n\n\n<p>To address this, an amendment to the proposal is to replace \nLastException with a stack is under consideration. This would allow the \ndeveloper to see all of the exceptions that were thrown in reverse \nchronological order.<\/p>\n\n\n\n<p>Another option being considered is the ability to specify a jump target.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#exception mode deferred error_handler\n[...]\nreturn;\n\nerror_handler:\n\/\/log error\n#exception resume next\n<\/code><\/pre>\n\n\n\n<p>If the \u201cnext\u201d modifier is omitted, the application will retry the failed statement rather than continuing onto the next line.<\/p>\n\n\n\n<p>The use of both structured and deferred error handling in the same \nfunction can be problematic from a compiler standpoint. Deferred mode \nfundamentally changes the way the code is compiled, much like how C# \nimplements closures and async\/await without CLR support. In order to \nsimplify the changes needed for the compiler, another syntax is being \nconsidered. This would use the same type of syntax we see with unsafe \nand checked blocks.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>deferred \n{\n    DownloadFiles();\n    ParseAndConvertFiles();\n    ImportFiles();\n}\n<\/code><\/pre>\n\n\n\n<p>Due to the magnitude of the change, this proposal is unlikely to be adopted before C# 9.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When writing robust software, there is often a need to perform a series of retrievable operations. In order to make the system robust, each operation in the series can be coded so it is independent of the status of the previous operation. As a concrete example, consider a file processing pipeline. The first step in&hellip;&nbsp;<a href=\"http:\/\/www.smart-bricks.net\/index.php\/2019\/04\/25\/c-futures-deferred-error-handling\/\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">C# Futures: Deferred Error Handling<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":70,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"categories":[1],"tags":[21,14],"class_list":["post-765","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-c","tag-development"],"_links":{"self":[{"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/posts\/765","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/comments?post=765"}],"version-history":[{"count":1,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/posts\/765\/revisions"}],"predecessor-version":[{"id":766,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/posts\/765\/revisions\/766"}],"wp:attachment":[{"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/media?parent=765"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/categories?post=765"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/tags?post=765"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}