{"id":3241,"date":"2011-02-14T12:19:00","date_gmt":"2011-02-14T12:19:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/subterranean-il-filter-exception-handlers\/"},"modified":"2021-04-29T15:30:54","modified_gmt":"2021-04-29T15:30:54","slug":"subterranean-il-filter-exception-handlers","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/subterranean-il-filter-exception-handlers\/","title":{"rendered":"Subterranean IL: Filter exception handlers"},"content":{"rendered":"<p><code>Filter<\/code> handlers are the second type of exception handler that aren&#8217;t accessible from C#. Unlike the other handler types, which have defined conditions for when the handlers execute, <code>filter<\/code> lets you use custom logic to determine whether the handler should be run. However, similar to a <code>catch<\/code> block, the <code>filter<\/code> block does not get run if control flow exits the block without throwing an exception.<\/p>\n<p><b>Introducing filter blocks<\/b><\/p>\n<p>An example of a filter block in IL is the following: <\/p>\n<pre>.try {\n    \/\/ try block\n}\nfilter {\n    \/\/ filter block\n    endfilter\n}{\n    \/\/ filter handler\n}<\/pre>\n<p> or, in v1 syntax, <\/p>\n<pre>TryStart:\n   \/\/ try block\n   \nTryEnd:\nFilterStart:\n   \/\/ filter block\n   \nHandlerStart:\n   \/\/ filter handler\nHandlerEnd:\n\n.try TryStart to TryEnd\n    filter FilterStart\n        handler HandlerStart to HandlerEnd<\/pre>\n<p>  In the v1 syntax there is no end label specified for the filter block. This is because the filter block must come immediately before the filter handler; the end of the filter block is the start of the filter handler.<\/p>\n<p>The filter block indicates to the CLR whether the filter handler should be executed using a boolean value on the stack when the <code>endfilter<\/code> instruction is run; true\/non-zero if it is to be executed, false\/zero if it isn&#8217;t. At the start of the filter block, and the corresponding filter handler, a reference to the exception thrown is pushed onto the stack as a raw <code>object<\/code> (you have to manually cast to <code>System.Exception<\/code>).<\/p>\n<p>The allowed IL inside a filter block is tightly controlled; you aren&#8217;t allowed branches outside the block, <code>rethrow<\/code> instructions, and other exception handling clauses. You can, however, use <code>call<\/code> and <code>callvirt<\/code> instructions to call other methods.<\/p>\n<p><b>Filter block logic<\/b><\/p>\n<p>To demonstrate filter block logic, in this example I&#8217;m filtering on whether there&#8217;s a particular key in the <code>Data<\/code> dictionary of the thrown exception: <\/p>\n<pre>.try {\n    \/\/ try block\n}\nfilter {\n    \/\/ Filter starts with exception object on stack\n    \/\/ C# code: ((Exception)e).Data.Contains(\"MyExceptionDataKey\")\n    \/\/ only execute handler if Contains returns true\n    \n    castclass [mscorlib]System.Exception\n    callvirt instance class [mscorlib]System.Collections.IDictionary \n        [mscorlib]System.Exception::get_Data()\n    ldstr \"MyExceptionDataKey\"\n    callvirt instance bool \n        [mscorlib]System.Collections.IDictionary::Contains(object)\n    endfilter\n}{\n    \/\/ filter handler\n    \/\/ Also starts off with exception object on stack\n    \n    callvirt instance string [mscorlib]System.Object::ToString()\n    call void [mscorlib]System.Console::WriteLine(string)\n}<\/pre>\n<p><b>Conclusion<\/b><\/p>\n<p>Filter exception handlers are another exception handler type that isn&#8217;t accessible from C#, however, just like <code>fault<\/code> handlers, the behaviour can be replicated using a normal catch block: <\/p>\n<pre>try {\n    \/\/ try block\n}\ncatch (Exception e) {\n    if (!FilterLogic(e)) throw;\n    \n    \/\/ handler logic\n}<\/pre>\n<p>So, it&#8217;s not that great a loss, but it&#8217;s still annoying that this functionality isn&#8217;t directly accessible. Well, <a href=\"http:\/\/blogs.msdn.com\/b\/ericgu\/archive\/2004\/01\/12\/57985.aspx\">every feature starts off with minus 100 points<\/a>, so it&#8217;s understandable why something like this didn&#8217;t make it into the C# compiler ahead of a different feature.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Filter handlers are the second type of exception handler that aren&#8217;t accessible from C#. Unlike the other handler types, which have defined conditions for when the handlers execute, filter lets you use custom logic to determine whether the handler should be run. However, similar to a catch block, the filter block does not get run&#8230;&hellip;<\/p>\n","protected":false},"author":186659,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538,2],"tags":[],"coauthors":[],"class_list":["post-3241","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","category-blogs"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3241","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/186659"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=3241"}],"version-history":[{"count":2,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3241\/revisions"}],"predecessor-version":[{"id":41995,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3241\/revisions\/41995"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=3241"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=3241"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=3241"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=3241"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}